Example #1
0
void VertexShaderCache::Init()
{
  const D3D11_INPUT_ELEMENT_DESC simpleelems[2] = {
      {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
      {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},

  };
  const D3D11_INPUT_ELEMENT_DESC clearelems[2] = {
      {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
      {"COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
  };

  unsigned int cbsize = ROUND_UP(sizeof(VertexShaderConstants), 16);  // must be a multiple of 16
  D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(cbsize, D3D11_BIND_CONSTANT_BUFFER,
                                                D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
  HRESULT hr = D3D::device->CreateBuffer(&cbdesc, nullptr, &vscbuf);
  CHECK(hr == S_OK, "Create vertex shader constant buffer (size=%u)", cbsize);
  D3D::SetDebugObjectName((ID3D11DeviceChild*)vscbuf,
                          "vertex shader constant buffer used to emulate the GX pipeline");

  D3DBlob* blob;
  D3D::CompileVertexShader(simple_shader_code, &blob);
  D3D::device->CreateInputLayout(simpleelems, 2, blob->Data(), blob->Size(), &SimpleLayout);
  SimpleVertexShader = D3D::CreateVertexShaderFromByteCode(blob);
  if (SimpleLayout == nullptr || SimpleVertexShader == nullptr)
    PanicAlert("Failed to create simple vertex shader or input layout at %s %d\n", __FILE__,
               __LINE__);
  blob->Release();
  D3D::SetDebugObjectName((ID3D11DeviceChild*)SimpleVertexShader, "simple vertex shader");
  D3D::SetDebugObjectName((ID3D11DeviceChild*)SimpleLayout, "simple input layout");

  D3D::CompileVertexShader(clear_shader_code, &blob);
  D3D::device->CreateInputLayout(clearelems, 2, blob->Data(), blob->Size(), &ClearLayout);
  ClearVertexShader = D3D::CreateVertexShaderFromByteCode(blob);
  if (ClearLayout == nullptr || ClearVertexShader == nullptr)
    PanicAlert("Failed to create clear vertex shader or input layout at %s %d\n", __FILE__,
               __LINE__);
  blob->Release();
  D3D::SetDebugObjectName((ID3D11DeviceChild*)ClearVertexShader, "clear vertex shader");
  D3D::SetDebugObjectName((ID3D11DeviceChild*)ClearLayout, "clear input layout");

  Clear();

  if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
    File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX));

  SETSTAT(stats.numVertexShadersCreated, 0);
  SETSTAT(stats.numVertexShadersAlive, 0);

  std::string cache_filename =
      StringFromFormat("%sdx11-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
                       SConfig::GetInstance().m_strUniqueID.c_str());
  VertexShaderCacheInserter inserter;
  g_vs_disk_cache.OpenAndRead(cache_filename, inserter);

  if (g_Config.bEnableShaderDebugging)
    Clear();

  last_entry = nullptr;
}
Example #2
0
void DX11::Shader::UpdateConstantBuffer(ID3D11DeviceContext * context, std::vector<float> & constants, ID3D11Buffer ** buffer)
{
	while((constants.size() % 4) != 0)
	{
		constants.push_back(0.0f);
	}

	if(*buffer)
	{
		context->UpdateSubresource(*buffer, 0, 0, constants.data(), 0, 0);
	}
	else
	{
		ID3D11Device * device = 0;
		context->GetDevice(&device);

		if(device)
		{
			D3D11_SUBRESOURCE_DATA data = { 0 };
			data.pSysMem = constants.data();

			device->CreateBuffer(
				&CD3D11_BUFFER_DESC(sizeof(float) * constants.size(), D3D11_BIND_CONSTANT_BUFFER),
				&data,
				buffer);

			device->Release();
		}
	}
}
void GeometryShaderCache::Init()
{
  unsigned int gbsize = Common::AlignUp(static_cast<unsigned int>(sizeof(GeometryShaderConstants)),
                                        16);  // must be a multiple of 16
  D3D11_BUFFER_DESC gbdesc = CD3D11_BUFFER_DESC(gbsize, D3D11_BIND_CONSTANT_BUFFER,
                                                D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
  HRESULT hr = D3D::device->CreateBuffer(&gbdesc, nullptr, &gscbuf);
  CHECK(hr == S_OK, "Create geometry shader constant buffer (size=%u)", gbsize);
  D3D::SetDebugObjectName((ID3D11DeviceChild*)gscbuf,
                          "geometry shader constant buffer used to emulate the GX pipeline");

  // used when drawing clear quads
  ClearGeometryShader = D3D::CompileAndCreateGeometryShader(clear_shader_code);
  CHECK(ClearGeometryShader != nullptr, "Create clear geometry shader");
  D3D::SetDebugObjectName((ID3D11DeviceChild*)ClearGeometryShader, "clear geometry shader");

  // used for buffer copy
  CopyGeometryShader = D3D::CompileAndCreateGeometryShader(copy_shader_code);
  CHECK(CopyGeometryShader != nullptr, "Create copy geometry shader");
  D3D::SetDebugObjectName((ID3D11DeviceChild*)CopyGeometryShader, "copy geometry shader");

  Clear();

  if (g_ActiveConfig.bShaderCache)
    LoadShaderCache();
}
void GeometryShaderCache::Init()
{
	unsigned int gbsize = ROUND_UP(sizeof(GeometryShaderConstants), 16); // must be a multiple of 16
	D3D11_BUFFER_DESC gbdesc = CD3D11_BUFFER_DESC(gbsize, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
	HRESULT hr = D3D::device->CreateBuffer(&gbdesc, nullptr, &gscbuf);
	CHECK(hr == S_OK, "Create geometry shader constant buffer (size=%u)", gbsize);
	D3D::SetDebugObjectName((ID3D11DeviceChild*)gscbuf, "geometry shader constant buffer used to emulate the GX pipeline");

	// used when drawing clear quads
	ClearGeometryShader = D3D::CompileAndCreateGeometryShader(clear_shader_code);
	CHECK(ClearGeometryShader != nullptr, "Create clear geometry shader");
	D3D::SetDebugObjectName((ID3D11DeviceChild*)ClearGeometryShader, "clear geometry shader");

	// used for buffer copy
	CopyGeometryShader = D3D::CompileAndCreateGeometryShader(copy_shader_code);
	CHECK(CopyGeometryShader != nullptr, "Create copy geometry shader");
	D3D::SetDebugObjectName((ID3D11DeviceChild*)CopyGeometryShader, "copy geometry shader");

	Clear();

	if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
		File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX));

	std::string cache_filename = StringFromFormat("%sdx11-%s-gs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
			SConfig::GetInstance().m_strUniqueID.c_str());
	GeometryShaderCacheInserter inserter;
	g_gs_disk_cache.OpenAndRead(cache_filename, inserter);

	if (g_Config.bEnableShaderDebugging)
		Clear();

	last_entry = nullptr;
}
Example #5
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);
	}
}
Example #6
0
void VertexShaderCache::Init()
{
  const D3D11_INPUT_ELEMENT_DESC simpleelems[2] = {
      {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
      {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},

  };
  const D3D11_INPUT_ELEMENT_DESC clearelems[2] = {
      {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
      {"COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
  };

  unsigned int cbsize = Common::AlignUp(static_cast<unsigned int>(sizeof(VertexShaderConstants)),
                                        16);  // must be a multiple of 16
  D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(cbsize, D3D11_BIND_CONSTANT_BUFFER,
                                                D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
  HRESULT hr = D3D::device->CreateBuffer(&cbdesc, nullptr, &vscbuf);
  CHECK(hr == S_OK, "Create vertex shader constant buffer (size=%u)", cbsize);
  D3D::SetDebugObjectName(vscbuf, "vertex shader constant buffer used to emulate the GX pipeline");

  D3DBlob* blob;
  D3D::CompileVertexShader(simple_shader_code, &blob);
  D3D::device->CreateInputLayout(simpleelems, 2, blob->Data(), blob->Size(), &SimpleLayout);
  SimpleVertexShader = D3D::CreateVertexShaderFromByteCode(blob);
  if (SimpleLayout == nullptr || SimpleVertexShader == nullptr)
    PanicAlert("Failed to create simple vertex shader or input layout at %s %d\n", __FILE__,
               __LINE__);
  blob->Release();
  D3D::SetDebugObjectName(SimpleVertexShader, "simple vertex shader");
  D3D::SetDebugObjectName(SimpleLayout, "simple input layout");

  D3D::CompileVertexShader(clear_shader_code, &blob);
  D3D::device->CreateInputLayout(clearelems, 2, blob->Data(), blob->Size(), &ClearLayout);
  ClearVertexShader = D3D::CreateVertexShaderFromByteCode(blob);
  if (ClearLayout == nullptr || ClearVertexShader == nullptr)
    PanicAlert("Failed to create clear vertex shader or input layout at %s %d\n", __FILE__,
               __LINE__);
  blob->Release();
  D3D::SetDebugObjectName(ClearVertexShader, "clear vertex shader");
  D3D::SetDebugObjectName(ClearLayout, "clear input layout");

  Clear();

  SETSTAT(stats.numVertexShadersCreated, 0);
  SETSTAT(stats.numVertexShadersAlive, 0);

  if (g_ActiveConfig.bShaderCache)
    LoadShaderCache();

  g_async_compiler = std::make_unique<VideoCommon::AsyncShaderCompiler>();
  g_async_compiler->ResizeWorkerThreads(g_ActiveConfig.CanPrecompileUberShaders() ?
                                            g_ActiveConfig.GetShaderPrecompilerThreads() :
                                            g_ActiveConfig.GetShaderCompilerThreads());

  if (g_ActiveConfig.CanPrecompileUberShaders())
    QueueUberShaderCompiles();
}
Example #7
0
void InitUtils()
{
	util_vbuf = new UtilVertexBuffer(0x4000);

	float border[4] = { 0.f, 0.f, 0.f, 0.f };
	D3D11_SAMPLER_DESC samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_POINT, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, 0.f, 1, D3D11_COMPARISON_ALWAYS, border, 0.f, 0.f);
	HRESULT hr = D3D::device->CreateSamplerState(&samDesc, &point_copy_sampler);
	if (FAILED(hr)) PanicAlert("Failed to create sampler state at %s %d\n", __FILE__, __LINE__);
	else SetDebugObjectName((ID3D11DeviceChild*)point_copy_sampler, "point copy sampler state");

	samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, 0.f, 1, D3D11_COMPARISON_ALWAYS, border, 0.f, 0.f);
	hr = D3D::device->CreateSamplerState(&samDesc, &linear_copy_sampler);
	if (FAILED(hr)) PanicAlert("Failed to create sampler state at %s %d\n", __FILE__, __LINE__);
	else SetDebugObjectName((ID3D11DeviceChild*)linear_copy_sampler, "linear copy sampler state");

	// cached data used to avoid unnecessarily reloading the vertex buffers
	memset(&tex_quad_data, 0, sizeof(tex_quad_data));
	memset(&tex_sub_quad_data, 0, sizeof(tex_sub_quad_data));
	memset(&draw_quad_data, 0, sizeof(draw_quad_data));
	memset(&clear_quad_data, 0, sizeof(clear_quad_data));

	// make sure to properly load the vertex data whenever the corresponding functions get called the first time
	stq_observer = stsq_observer = cq_observer = clearq_observer = true;
	util_vbuf->AddWrapObserver(&stq_observer);
	util_vbuf->AddWrapObserver(&stsq_observer);
	util_vbuf->AddWrapObserver(&cq_observer);
	util_vbuf->AddWrapObserver(&clearq_observer);

	font.Init();
	
	// Create resources for encoder quads

	// Create vertex quad
	D3D11_BUFFER_DESC bd = CD3D11_BUFFER_DESC(sizeof(ENCODER_QUAD_VERTS),
		D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_IMMUTABLE);
	D3D11_SUBRESOURCE_DATA srd = { ENCODER_QUAD_VERTS, 0, 0 };
	hr = D3D::device->CreateBuffer(&bd, &srd, &s_encoderQuad);
	CHECK(SUCCEEDED(hr), "create encoder quad buffer");

	// Create vertex shader
	D3DBlob* blob;
	D3D::CompileVertexShader(ENCODER_VS, sizeof(ENCODER_VS), &blob);
	s_encoderVShader = D3D::CreateVertexShaderFromByteCode(blob);
	CHECK(SUCCEEDED(hr), "create encoder vertex shader");

	// Create input layout
	hr = D3D::device->CreateInputLayout(ENCODER_QUAD_LAYOUT_DESC,
		sizeof(ENCODER_QUAD_LAYOUT_DESC) / sizeof(D3D11_INPUT_ELEMENT_DESC),
		blob->Data(), blob->Size(), &s_encoderQuadLayout);
	CHECK(SUCCEEDED(hr), "create encoder input layout");

	blob->Release();

	// Create vertex shader for encoder quads with texture coords
	s_encoderTexVShader = D3D::CompileAndCreateVertexShader(ENCODER_TEX_VS, sizeof(ENCODER_TEX_VS));
}
Example #8
0
ConstantBufferPtr ConstantBuffer::Create(ID3D11Device* pDevice, UINT size)
{
	ConstantBufferPtr p(new ConstantBuffer);

	D3D11_BUFFER_DESC bd = CD3D11_BUFFER_DESC((size+15)&~15,
		D3D11_BIND_CONSTANT_BUFFER);
	CHECK_HR(pDevice->CreateBuffer(&bd, NULL, &p->m_pBuffer));

	return p;
}
Example #9
0
DX11::TextureShader::TextureShader(ID3D11Device * device) :
	DX11::Shader(device, Type::Texture), standardConstBuffer(0), pixelObject(0)
{
	device->CreateBuffer(
		&CD3D11_BUFFER_DESC(sizeof(StandardConstants), D3D11_BIND_CONSTANT_BUFFER),
		0,
		&standardConstBuffer);

	ZeroMemory(paramConstBuffers, NUM_PARAM_BUFFERS * sizeof(void*));
}
Example #10
0
DX11::ModelShader::ModelShader(ID3D11Device * device) 
	: DX11::Shader(device, Type::Model)
	, vertexConstBuffer(0)
	, pixelConstBuffer(0)
	, indirectArgsBuffer(0)
	, currentTechnique(0)
	, indirectPrimitive(PrimitiveUnknown)
{
	device->CreateBuffer(
		&CD3D11_BUFFER_DESC(sizeof(VertexConstants), D3D11_BIND_CONSTANT_BUFFER),
		0,
		&vertexConstBuffer);
	device->CreateBuffer(
		&CD3D11_BUFFER_DESC(sizeof(PixelConstants), D3D11_BIND_CONSTANT_BUFFER),
		0,
		&pixelConstBuffer);
	device->CreateBuffer(
		&CD3D11_BUFFER_DESC(sizeof(LightConstants)* MAX_LIGHTS, D3D11_BIND_CONSTANT_BUFFER),
		0,
		&lightParamsBuffer);
}
Example #11
0
void PixelShaderCache::Init()
{
  unsigned int cbsize = Common::AlignUp(static_cast<unsigned int>(sizeof(PixelShaderConstants)),
                                        16);  // must be a multiple of 16
  D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(cbsize, D3D11_BIND_CONSTANT_BUFFER,
                                                D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
  D3D::device->CreateBuffer(&cbdesc, nullptr, &pscbuf);
  CHECK(pscbuf != nullptr, "Create pixel shader constant buffer");
  D3D::SetDebugObjectName((ID3D11DeviceChild*)pscbuf,
                          "pixel shader constant buffer used to emulate the GX pipeline");

  // used when drawing clear quads
  s_ClearProgram = D3D::CompileAndCreatePixelShader(clear_program_code);
  CHECK(s_ClearProgram != nullptr, "Create clear pixel shader");
  D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ClearProgram, "clear pixel shader");

  // used for anaglyph stereoscopy
  s_AnaglyphProgram = D3D::CompileAndCreatePixelShader(anaglyph_program_code);
  CHECK(s_AnaglyphProgram != nullptr, "Create anaglyph pixel shader");
  D3D::SetDebugObjectName((ID3D11DeviceChild*)s_AnaglyphProgram, "anaglyph pixel shader");

  // used when copying/resolving the color buffer
  s_ColorCopyProgram[0] = D3D::CompileAndCreatePixelShader(color_copy_program_code);
  CHECK(s_ColorCopyProgram[0] != nullptr, "Create color copy pixel shader");
  D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ColorCopyProgram[0], "color copy pixel shader");

  // used for color conversion
  s_ColorMatrixProgram[0] = D3D::CompileAndCreatePixelShader(color_matrix_program_code);
  CHECK(s_ColorMatrixProgram[0] != nullptr, "Create color matrix pixel shader");
  D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ColorMatrixProgram[0], "color matrix pixel shader");

  // used for depth copy
  s_DepthMatrixProgram[0] = D3D::CompileAndCreatePixelShader(depth_matrix_program);
  CHECK(s_DepthMatrixProgram[0] != nullptr, "Create depth matrix pixel shader");
  D3D::SetDebugObjectName((ID3D11DeviceChild*)s_DepthMatrixProgram[0], "depth matrix pixel shader");

  Clear();

  if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
    File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX));

  SETSTAT(stats.numPixelShadersCreated, 0);
  SETSTAT(stats.numPixelShadersAlive, 0);

  std::string cache_filename =
      StringFromFormat("%sdx11-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
                       SConfig::GetInstance().m_strGameID.c_str());
  PixelShaderCacheInserter inserter;
  g_ps_disk_cache.OpenAndRead(cache_filename, inserter);

  last_entry = nullptr;
}
Example #12
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();
}
Example #13
0
void MeshRenderer::Init(int numVertices, const MeshVertex* vertices, const MeshColor* color, const MeshSkin* skin, int numIndices, const AFIndex* indices)
{
	Destroy();

	static InputElement layout[] = {
		CInputElement("COLOR", SF_R8G8B8A8_UNORM, 0),
		CInputElement("TEXCOORD", SF_R32G32_FLOAT, 4),
	};
	shaderId = shaderMan.Create("skin", layout, dimof(layout), BM_NONE, DSM_DEPTH_ENABLE, CM_CW);

	deviceMan11.GetDevice()->CreateBuffer(&CD3D11_BUFFER_DESC(numVertices * sizeof(MeshVertex), D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS, D3D11_USAGE_DEFAULT, 0, D3D11_RESOURCE_MISC_BUFFER_STRUCTURED, sizeof(MeshVertex)), nullptr, &skinnedPosBuffer);
	D3D11_SUBRESOURCE_DATA subresData = { vertices, 0, 0 };
	deviceMan11.GetDevice()->CreateBuffer(&CD3D11_BUFFER_DESC(numVertices * sizeof(MeshVertex), D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0, D3D11_RESOURCE_MISC_BUFFER_STRUCTURED, sizeof(MeshVertex)), &subresData, &posBuffer);
	subresData.pSysMem = skin;
	HRESULT hr = deviceMan11.GetDevice()->CreateBuffer(&CD3D11_BUFFER_DESC(numVertices * sizeof(MeshSkin), D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0, D3D11_RESOURCE_MISC_BUFFER_STRUCTURED, sizeof(MeshSkin)), &subresData, &skinBuffer);
	colorBuffer = afCreateVertexBuffer(numVertices * sizeof(MeshColor), color);
	iboId = afCreateIndexBuffer(indices, numIndices);
	uboId = afCreateUBO(sizeof(MeshConstantBuffer));

	int strides[] = {sizeof(MeshColor)};
	VBOID vbos[] = {colorBuffer};
	vao = afCreateVAO(layout, dimof(layout), 1, vbos, strides, iboId);
	sampler = afCreateSampler(SF_MIPMAP, SW_REPEAT);
}
Example #14
0
void LineGeometryShader::Init()
{
	m_ready = false;

	HRESULT hr;

	// Create constant buffer for uploading data to geometry shader

	D3D11_BUFFER_DESC bd = CD3D11_BUFFER_DESC(sizeof(LineGSParams_Padded),
		D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
	hr = D3D::device->CreateBuffer(&bd, nullptr, &m_paramsBuffer);
	CHECK(SUCCEEDED(hr), "create line geometry shader params buffer");
	D3D::SetDebugObjectName(m_paramsBuffer, "line geometry shader params buffer");

	m_ready = true;
}
Example #15
0
void PSTextureEncoder::Init()
{
  // TODO: Move this to a constant somewhere in common.
  TextureConfig encoding_texture_config(EFB_WIDTH * 4, 1024, 1, 1, AbstractTextureFormat::BGRA8,
                                        true);
  m_encoding_render_texture = g_renderer->CreateTexture(encoding_texture_config);
  m_encoding_readback_texture =
      g_renderer->CreateStagingTexture(StagingTextureType::Readback, encoding_texture_config);
  _assert_(m_encoding_render_texture && m_encoding_readback_texture);

  // Create constant buffer for uploading data to shaders
  D3D11_BUFFER_DESC bd = CD3D11_BUFFER_DESC(sizeof(EFBEncodeParams), D3D11_BIND_CONSTANT_BUFFER);
  HRESULT hr = D3D::device->CreateBuffer(&bd, nullptr, &m_encode_params);
  CHECK(SUCCEEDED(hr), "create efb encode params buffer");
  D3D::SetDebugObjectName(m_encode_params, "efb encoder params buffer");
}
Example #16
0
void PixelShaderCache::Init()
{
	unsigned int cbsize = ((sizeof(PixelShaderConstants))&(~0xf))+0x10; // must be a multiple of 16
	D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(cbsize, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
	D3D::device->CreateBuffer(&cbdesc, NULL, &pscbuf);
	CHECK(pscbuf!=NULL, "Create pixel shader constant buffer");
	D3D::SetDebugObjectName((ID3D11DeviceChild*)pscbuf, "pixel shader constant buffer used to emulate the GX pipeline");

	// used when drawing clear quads
	s_ClearProgram = D3D::CompileAndCreatePixelShader(clear_program_code, sizeof(clear_program_code));
	CHECK(s_ClearProgram!=NULL, "Create clear pixel shader");
	D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ClearProgram, "clear pixel shader");

	// used when copying/resolving the color buffer
	s_ColorCopyProgram[0] = D3D::CompileAndCreatePixelShader(color_copy_program_code, sizeof(color_copy_program_code));
	CHECK(s_ColorCopyProgram[0]!=NULL, "Create color copy pixel shader");
	D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ColorCopyProgram[0], "color copy pixel shader");

	// used for color conversion
	s_ColorMatrixProgram[0] = D3D::CompileAndCreatePixelShader(color_matrix_program_code, sizeof(color_matrix_program_code));
	CHECK(s_ColorMatrixProgram[0]!=NULL, "Create color matrix pixel shader");
	D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ColorMatrixProgram[0], "color matrix pixel shader");

	// used for depth copy
	s_DepthMatrixProgram[0] = D3D::CompileAndCreatePixelShader(depth_matrix_program, sizeof(depth_matrix_program));
	CHECK(s_DepthMatrixProgram[0]!=NULL, "Create depth matrix pixel shader");
	D3D::SetDebugObjectName((ID3D11DeviceChild*)s_DepthMatrixProgram[0], "depth matrix pixel shader");

	Clear();

	if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
		File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX).c_str());

	SETSTAT(stats.numPixelShadersCreated, 0);
	SETSTAT(stats.numPixelShadersAlive, 0);

	char cache_filename[MAX_PATH];
	sprintf(cache_filename, "%sdx11-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
			SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
	PixelShaderCacheInserter inserter;
	g_ps_disk_cache.OpenAndRead(cache_filename, inserter);

	if (g_Config.bEnableShaderDebugging)
		Clear();

	last_entry = NULL;
}
Example #17
0
void VertexManager::CreateDeviceObjects()
{
	D3D11_BUFFER_DESC bufdesc = CD3D11_BUFFER_DESC(MAX_BUFFER_SIZE,
		D3D11_BIND_INDEX_BUFFER | D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);

	m_vertexDrawOffset = 0;
	m_indexDrawOffset = 0;

	for (int i = 0; i < MAX_BUFFER_COUNT; i++)
	{
		m_buffers[i] = nullptr;
		CHECK(SUCCEEDED(D3D::device->CreateBuffer(&bufdesc, nullptr, D3D::ToAddr(m_buffers[i]))), "Failed to create buffer.");
		D3D::SetDebugObjectName((ID3D11DeviceChild*)m_buffers[i].get(), "Buffer of VertexManager");
	}

	m_currentBuffer = 0;
	m_bufferCursor = MAX_BUFFER_SIZE;
}
void PSTextureEncoder::Init()
{
	m_ready = false;

	HRESULT hr;

	// Create output texture RGBA format
	D3D11_TEXTURE2D_DESC t2dd = CD3D11_TEXTURE2D_DESC(
		DXGI_FORMAT_B8G8R8A8_UNORM,
		EFB_WIDTH * 4, EFB_HEIGHT / 4, 1, 1, D3D11_BIND_RENDER_TARGET);
	hr = D3D::device->CreateTexture2D(&t2dd, nullptr, &m_out);
	CHECK(SUCCEEDED(hr), "create efb encode output texture");
	D3D::SetDebugObjectName(m_out, "efb encoder output texture");

	// Create output render target view
	D3D11_RENDER_TARGET_VIEW_DESC rtvd = CD3D11_RENDER_TARGET_VIEW_DESC(m_out,
		D3D11_RTV_DIMENSION_TEXTURE2D, DXGI_FORMAT_B8G8R8A8_UNORM);
	hr = D3D::device->CreateRenderTargetView(m_out, &rtvd, &m_outRTV);
	CHECK(SUCCEEDED(hr), "create efb encode output render target view");
	D3D::SetDebugObjectName(m_outRTV, "efb encoder output rtv");

	// Create output staging buffer
	t2dd.Usage = D3D11_USAGE_STAGING;
	t2dd.BindFlags = 0;
	t2dd.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
	hr = D3D::device->CreateTexture2D(&t2dd, nullptr, &m_outStage);
	CHECK(SUCCEEDED(hr), "create efb encode output staging buffer");
	D3D::SetDebugObjectName(m_outStage, "efb encoder output staging buffer");

	// Create constant buffer for uploading data to shaders
	D3D11_BUFFER_DESC bd = CD3D11_BUFFER_DESC(sizeof(EFBEncodeParams),
		D3D11_BIND_CONSTANT_BUFFER);
	hr = D3D::device->CreateBuffer(&bd, nullptr, &m_encodeParams);
	CHECK(SUCCEEDED(hr), "create efb encode params buffer");
	D3D::SetDebugObjectName(m_encodeParams, "efb encoder params buffer");

	m_ready = true;
}
Example #19
0
void BBox::Init()
{
	if (g_ActiveConfig.backend_info.bSupportsBBox)
	{
		// Create 2 buffers here.
		// First on Default pool.
		auto desc = CD3D11_BUFFER_DESC(4 * sizeof(s32), D3D11_BIND_UNORDERED_ACCESS, D3D11_USAGE_DEFAULT, 0, 0, 4);
		s_values[0] = s_values[1] = s_values[2] = s_values[3] = 0;
		D3D11_SUBRESOURCE_DATA data;
		data.pSysMem = s_values;
		data.SysMemPitch = 4 * sizeof(s32);
		data.SysMemSlicePitch = 0;
		HRESULT hr;
		hr = D3D::device->CreateBuffer(&desc, &data, ToAddr(s_bbox_buffer));
		CHECK(SUCCEEDED(hr), "Create BoundingBox buffer.");
		D3D::SetDebugObjectName(s_bbox_buffer.get(), "BoundingBox buffer");
		// Second to use as a staging buffer.
		desc.Usage = D3D11_USAGE_STAGING;
		desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
		desc.BindFlags = 0;
		hr = D3D::device->CreateBuffer(&desc, nullptr, ToAddr(s_bbox_staging_buffer));
		CHECK(SUCCEEDED(hr), "Create BoundingBox staging buffer.");
		D3D::SetDebugObjectName(s_bbox_staging_buffer.get(), "BoundingBox staging buffer");
		// UAV is required to allow concurrent access.
		D3D11_UNORDERED_ACCESS_VIEW_DESC UAVdesc = {};
		UAVdesc.Format = DXGI_FORMAT_R32_SINT;
		UAVdesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
		UAVdesc.Buffer.FirstElement = 0;
		UAVdesc.Buffer.Flags = 0;
		UAVdesc.Buffer.NumElements = 4;
		hr = D3D::device->CreateUnorderedAccessView(s_bbox_buffer.get(), &UAVdesc, ToAddr(s_bbox_uav));
		CHECK(SUCCEEDED(hr), "Create BoundingBox UAV.");
		s_cpu_dirty = true;
		s_gpu_dirty = true;
	}
}
//////////////////////////////////////////////////////////////////////////
// d3d11 constant buffer
cgl::CD3D11ConstantBuffer::CD3D11ConstantBuffer( UINT elementSize, D3D11_USAGE usage /*= D3D11_USAGE_DEFAULT*/, UINT cpuAccessFlags /*= 0*/, UINT miscFlags /*= 0*/ )
	: CD3D11Buffer(elementSize, CD3D11_BUFFER_DESC(0, D3D11_BIND_CONSTANT_BUFFER, usage, cpuAccessFlags, miscFlags, elementSize ))
{

}
//////////////////////////////////////////////////////////////////////////
// d3d11 index buffer
cgl::CD3D11IndexBuffer::CD3D11IndexBuffer( UINT elementSize, D3D11_USAGE usage /*= D3D11_USAGE_DEFAULT*/, UINT cpuAccessFlags /*= 0*/, UINT miscFlags /*= 0*/ )
	: CD3D11Buffer(elementSize, CD3D11_BUFFER_DESC(0, D3D11_BIND_INDEX_BUFFER, usage, cpuAccessFlags, miscFlags, elementSize ))
{

}
//////////////////////////////////////////////////////////////////////////
// d3d11 vertex buffer
cgl::CD3D11VertexBuffer::CD3D11VertexBuffer(UINT stride, D3D11_USAGE usage, UINT cpuAccessFlags, UINT miscFlags ) 
	: CD3D11Buffer(stride, CD3D11_BUFFER_DESC(0, D3D11_BIND_VERTEX_BUFFER, usage, cpuAccessFlags, miscFlags ))
{

}
Example #23
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;
	}
}
//////////////////////////////////////////////////////////////////////////
// d3d11 input buffer
cgl::util::CGLInputBuffer::CGLInputBuffer(cgl::core::PD3D11InputLayout pLayout, ICGLInputBufferDataProvider* pDataProvider, D3D11_USAGE usage /*= D3D11_USAGE_DEFAULT*/, DWORD cpuAccessFlags /*= 0*/) 
	: CGLBase("CD3D11InputBuffer"), CGLTypedBindable(this), m_pLayout(pLayout), m_pDataProvider(pDataProvider), m_desc(CD3D11_BUFFER_DESC(0, D3D11_BIND_VERTEX_BUFFER, usage, cpuAccessFlags))
{
	SetParam<UINT>(BIND_PARAM_STRIDE_UINT, 1);
	SetParam<UINT>(BIND_PARAM_OFFSET_UINT, 0);
	SetParam<UINT>(BIND_PARAM_SLOT_UINT, 0);
}
void VertexShaderCache::Init()
{
	const D3D11_INPUT_ELEMENT_DESC simpleelems[2] =
	{
		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0,  0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		
	};
	const D3D11_INPUT_ELEMENT_DESC clearelems[2] =
	{
		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0,  0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
	};

	unsigned int cbsize = ((sizeof(vsconstants))&(~0xf))+0x10; // must be a multiple of 16
	D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(cbsize, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
	HRESULT hr = D3D::device->CreateBuffer(&cbdesc, NULL, &vscbuf);
	CHECK(hr==S_OK, "Create vertex shader constant buffer (size=%u)", cbsize);
	D3D::SetDebugObjectName((ID3D11DeviceChild*)vscbuf, "vertex shader constant buffer used to emulate the GX pipeline");

	D3DBlob* blob;
	D3D::CompileVertexShader(simple_shader_code, sizeof(simple_shader_code), &blob);
	D3D::device->CreateInputLayout(simpleelems, 2, blob->Data(), blob->Size(), &SimpleLayout);
	SimpleVertexShader = D3D::CreateVertexShaderFromByteCode(blob);
	if (SimpleLayout == NULL || SimpleVertexShader == NULL) PanicAlert("Failed to create simple vertex shader or input layout at %s %d\n", __FILE__, __LINE__);
	blob->Release();
	D3D::SetDebugObjectName((ID3D11DeviceChild*)SimpleVertexShader, "simple vertex shader");
	D3D::SetDebugObjectName((ID3D11DeviceChild*)SimpleLayout, "simple input layout");

	D3D::CompileVertexShader(clear_shader_code, sizeof(clear_shader_code), &blob);
	D3D::device->CreateInputLayout(clearelems, 2, blob->Data(), blob->Size(), &ClearLayout);
	ClearVertexShader = D3D::CreateVertexShaderFromByteCode(blob);
	if (ClearLayout == NULL || ClearVertexShader == NULL) PanicAlert("Failed to create clear vertex shader or input layout at %s %d\n", __FILE__, __LINE__);
	blob->Release();
	D3D::SetDebugObjectName((ID3D11DeviceChild*)ClearVertexShader, "clear vertex shader");
	D3D::SetDebugObjectName((ID3D11DeviceChild*)ClearLayout, "clear input layout");

	Clear();

	// these values are hardcoded, they depend on internal D3DCompile behavior
	// TODO: Do this with D3DReflect or something instead
	unsigned int k;
	for (k = 0;k <  6;k++) vs_constant_offset_table[C_POSNORMALMATRIX+k]       =   0+4*k;
	for (k = 0;k <  4;k++) vs_constant_offset_table[C_PROJECTION+k]            =  24+4*k;
	for (k = 0;k <  4;k++) vs_constant_offset_table[C_MATERIALS+k]             =  40+4*k;
	for (k = 0;k < 40;k++) vs_constant_offset_table[C_LIGHTS+k]                =  56+4*k;
	for (k = 0;k < 24;k++) vs_constant_offset_table[C_TEXMATRICES+k]           = 216+4*k;
	for (k = 0;k < 64;k++) vs_constant_offset_table[C_TRANSFORMMATRICES+k]     = 312+4*k;	
	for (k = 0;k < 32;k++) vs_constant_offset_table[C_NORMALMATRICES+k]        = 568+4*k;	
	for (k = 0;k < 64;k++) vs_constant_offset_table[C_POSTTRANSFORMMATRICES+k] = 696+4*k;
	for (k = 0;k <  4;k++) vs_constant_offset_table[C_DEPTHPARAMS+k]		   = 952+4*k;	

	if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
		File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX).c_str());

	SETSTAT(stats.numVertexShadersCreated, 0);
	SETSTAT(stats.numVertexShadersAlive, 0);

	char cache_filename[MAX_PATH];
	sprintf(cache_filename, "%sdx11-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(),
			SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
	VertexShaderCacheInserter inserter;
	g_vs_disk_cache.OpenAndRead(cache_filename, inserter);

	if (g_Config.bEnableShaderDebugging)
		Clear();

	last_entry = NULL;
}
Example #26
0
	void init( HWND hWnd )
	{
		HRESULT hr;

		DXGI_SWAP_CHAIN_DESC scDesc;
		memset( &scDesc, 0, sizeof scDesc );
		scDesc.BufferDesc.Width = g_windowWidth;
		scDesc.BufferDesc.Height = g_windowHeight;
		scDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
		scDesc.BufferDesc.RefreshRate.Denominator = 1;
		scDesc.BufferDesc.RefreshRate.Numerator = 60;
		scDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
		scDesc.BufferCount = 1;
		scDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
		scDesc.SampleDesc.Count = 1;
		scDesc.Windowed = TRUE;
		scDesc.OutputWindow = hWnd;

		D3D_FEATURE_LEVEL features[] = { D3D_FEATURE_LEVEL_11_0 };

		UINT flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
#ifndef NDEBUG
		flags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

		IDXGISwapChain* swapChain;
		ID3D11Device* device;
		ID3D11DeviceContext* context;
		hr = D3D11CreateDeviceAndSwapChain(
			nullptr, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, features, ARRAYSIZE( features ),
			D3D11_SDK_VERSION, &scDesc, &swapChain, &device, &featureLevel_, &context );
		Assert( hr );
		swapChain_.reset( swapChain );
		device_.reset( device );
		context_.reset( context );

		ID3D11Texture2D* backBuffer;
		ID3D11RenderTargetView* backBufferRTV;
		hr = swapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), reinterpret_cast< void** >( &backBuffer ) );
		Assert( hr );
		hr = device_->CreateRenderTargetView( backBuffer, nullptr, &backBufferRTV );
		Assert( hr );
		backBufferRTV_.reset( backBufferRTV );
		backBuffer->Release();

		// Common state

		ID3D11RasterizerState* rs;
		D3D11_RASTERIZER_DESC rsDesc;
		memset( &rsDesc, 0, sizeof rsDesc );
		rsDesc.CullMode = D3D11_CULL_BACK;
		rsDesc.FillMode = D3D11_FILL_SOLID;
		rsDesc.DepthClipEnable = TRUE;
		hr = device_->CreateRasterizerState( &rsDesc, &rs );
		Assert( hr );
		rasterState_.reset( rs );

		// Body

		std::string binData;
		std::string vsBinData;
		ID3D11VertexShader* vs;
		binData = fileGetContents( "def.vs.cso" );
		hr = device_->CreateVertexShader(
			reinterpret_cast< const void* >( binData.c_str() ), binData.size(), nullptr, &vs );
		Assert( hr );
		modelVS_.reset( vs );
		vsBinData = binData;

		ID3D11PixelShader* ps;
		binData = fileGetContents( "def.ps.cso" );
		hr = device_->CreatePixelShader(
			reinterpret_cast< const void* >( binData.c_str() ), binData.size(), nullptr, &ps );
		Assert( hr );
		modelPS_.reset( ps );

		D3D11_BUFFER_DESC bufDesc = CD3D11_BUFFER_DESC( 64, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DEFAULT, 0 );
		ID3D11Buffer* buf;
		hr = device_->CreateBuffer( &bufDesc, nullptr, &buf );
		Assert( hr );
		modelCB_.reset( buf );

		// 四角錐ポリゴン
		static const MeshFormat pyramidVertex[] = {
			{ -1.0f,  0.0f, -1.0f, 0xFF33AAAA },
			{  1.0f,  0.0f, -1.0f, 0xFF33AAAA },
			{ -1.0f,  0.0f,  1.0f, 0xFF33AAAA },
		
			{ -1.0f,  0.0f,  1.0f, 0xFF33AAAA },
			{  1.0f,  0.0f, -1.0f, 0xFF33AAAA },
			{  1.0f,  0.0f,  1.0f, 0xFF33AAAA },

			{  1.0f,  0.0f, -1.0f, 0xFFEE33BB },
			{ -1.0f,  0.0f, -1.0f, 0xFFEE33BB },
			{  0.0f,  1.0f,  0.0f, 0xFFEE33BB },
		
			{ -1.0f,  0.0f, -1.0f, 0xFFCC33BB },
			{ -1.0f,  0.0f,  1.0f, 0xFFCC33BB },
			{  0.0f,  1.0f,  0.0f, 0xFFCC33BB },
		
			{ -1.0f,  0.0f,  1.0f, 0xFFAA33BB },
			{  1.0f,  0.0f,  1.0f, 0xFFAA33BB },
			{  0.0f,  1.0f,  0.0f, 0xFFAA33BB },
		
			{  1.0f,  0.0f,  1.0f, 0xFF8833BB },
			{  1.0f,  0.0f, -1.0f, 0xFF8833BB },
			{  0.0f,  1.0f,  0.0f, 0xFF8833BB },
		};

		bufDesc = CD3D11_BUFFER_DESC( sizeof pyramidVertex, D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_IMMUTABLE, 0 );
		D3D11_SUBRESOURCE_DATA subresData;
		subresData.pSysMem = pyramidVertex;
		subresData.SysMemPitch = subresData.SysMemSlicePitch = 0;
		hr = device_->CreateBuffer( &bufDesc, &subresData, &buf );
		Assert( hr );
		modelVB_.reset( buf );

		D3D11_INPUT_ELEMENT_DESC ieDesc[] = {
				{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
				{ "COLOR", 0, DXGI_FORMAT_B8G8R8A8_UNORM, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }
		};
		ID3D11InputLayout* il;
		hr = device_->CreateInputLayout( ieDesc, ARRAYSIZE( ieDesc ), vsBinData.data(), vsBinData.size(), &il );
		Assert( hr );
		modelIL_.reset( il );
	}
Example #27
0
void XFBEncoder::Init()
{
    HRESULT hr;

    // Create output texture

    // The pixel shader can generate one YUYV entry per pixel. One YUYV entry
    // is created for every two EFB pixels.
    D3D11_TEXTURE2D_DESC t2dd = CD3D11_TEXTURE2D_DESC(
                                    DXGI_FORMAT_R8G8B8A8_UNORM, MAX_XFB_WIDTH/2, MAX_XFB_HEIGHT, 1, 1,
                                    D3D11_BIND_RENDER_TARGET);
    hr = D3D::device->CreateTexture2D(&t2dd, nullptr, &m_out);
    CHECK(SUCCEEDED(hr), "create xfb encoder output texture");
    D3D::SetDebugObjectName(m_out, "xfb encoder output texture");

    // Create output render target view

    D3D11_RENDER_TARGET_VIEW_DESC rtvd = CD3D11_RENDER_TARGET_VIEW_DESC(m_out,
                                         D3D11_RTV_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8G8B8A8_UNORM);
    hr = D3D::device->CreateRenderTargetView(m_out, &rtvd, &m_outRTV);
    CHECK(SUCCEEDED(hr), "create xfb encoder output texture rtv");
    D3D::SetDebugObjectName(m_outRTV, "xfb encoder output rtv");

    // Create output staging buffer

    t2dd.Usage = D3D11_USAGE_STAGING;
    t2dd.BindFlags = 0;
    t2dd.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
    hr = D3D::device->CreateTexture2D(&t2dd, nullptr, &m_outStage);
    CHECK(SUCCEEDED(hr), "create xfb encoder output staging buffer");
    D3D::SetDebugObjectName(m_outStage, "xfb encoder output staging buffer");

    // Create constant buffer for uploading params to shaders

    D3D11_BUFFER_DESC bd = CD3D11_BUFFER_DESC(sizeof(XFBEncodeParams),
                           D3D11_BIND_CONSTANT_BUFFER);
    hr = D3D::device->CreateBuffer(&bd, nullptr, &m_encodeParams);
    CHECK(SUCCEEDED(hr), "create xfb encode params buffer");
    D3D::SetDebugObjectName(m_encodeParams, "xfb encoder params buffer");

    // Create vertex quad

    bd = CD3D11_BUFFER_DESC(sizeof(QUAD_VERTS), D3D11_BIND_VERTEX_BUFFER,
                            D3D11_USAGE_IMMUTABLE);
    D3D11_SUBRESOURCE_DATA srd = { QUAD_VERTS, 0, 0 };

    hr = D3D::device->CreateBuffer(&bd, &srd, &m_quad);
    CHECK(SUCCEEDED(hr), "create xfb encode quad vertex buffer");
    D3D::SetDebugObjectName(m_quad, "xfb encoder quad vertex buffer");

    // Create vertex shader

    D3DBlob* bytecode = nullptr;
    if (!D3D::CompileVertexShader(XFB_ENCODE_VS, &bytecode))
    {
        ERROR_LOG(VIDEO, "XFB encode vertex shader failed to compile");
        return;
    }

    hr = D3D::device->CreateVertexShader(bytecode->Data(), bytecode->Size(), nullptr, &m_vShader);
    CHECK(SUCCEEDED(hr), "create xfb encode vertex shader");
    D3D::SetDebugObjectName(m_vShader, "xfb encoder vertex shader");

    // Create input layout for vertex quad using bytecode from vertex shader

    hr = D3D::device->CreateInputLayout(QUAD_LAYOUT_DESC,
                                        sizeof(QUAD_LAYOUT_DESC)/sizeof(D3D11_INPUT_ELEMENT_DESC),
                                        bytecode->Data(), bytecode->Size(), &m_quadLayout);
    CHECK(SUCCEEDED(hr), "create xfb encode quad vertex layout");
    D3D::SetDebugObjectName(m_quadLayout, "xfb encoder quad layout");

    bytecode->Release();

    // Create pixel shader

    m_pShader = D3D::CompileAndCreatePixelShader(XFB_ENCODE_PS);
    if (!m_pShader)
    {
        ERROR_LOG(VIDEO, "XFB encode pixel shader failed to compile");
        return;
    }
    D3D::SetDebugObjectName(m_pShader, "xfb encoder pixel shader");

    // Create blend state

    D3D11_BLEND_DESC bld = CD3D11_BLEND_DESC(CD3D11_DEFAULT());
    hr = D3D::device->CreateBlendState(&bld, &m_xfbEncodeBlendState);
    CHECK(SUCCEEDED(hr), "create xfb encode blend state");
    D3D::SetDebugObjectName(m_xfbEncodeBlendState, "xfb encoder blend state");

    // Create depth state

    D3D11_DEPTH_STENCIL_DESC dsd = CD3D11_DEPTH_STENCIL_DESC(CD3D11_DEFAULT());
    dsd.DepthEnable = FALSE;
    hr = D3D::device->CreateDepthStencilState(&dsd, &m_xfbEncodeDepthState);
    CHECK(SUCCEEDED(hr), "create xfb encode depth state");
    D3D::SetDebugObjectName(m_xfbEncodeDepthState, "xfb encoder depth state");

    // Create rasterizer state

    D3D11_RASTERIZER_DESC rd = CD3D11_RASTERIZER_DESC(CD3D11_DEFAULT());
    rd.CullMode = D3D11_CULL_NONE;
    rd.DepthClipEnable = FALSE;
    hr = D3D::device->CreateRasterizerState(&rd, &m_xfbEncodeRastState);
    CHECK(SUCCEEDED(hr), "create xfb encode rasterizer state");
    D3D::SetDebugObjectName(m_xfbEncodeRastState, "xfb encoder rast state");

    // Create EFB texture sampler

    D3D11_SAMPLER_DESC sd = CD3D11_SAMPLER_DESC(CD3D11_DEFAULT());
    // FIXME: Should we really use point sampling here?
    sd.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
    hr = D3D::device->CreateSamplerState(&sd, &m_efbSampler);
    CHECK(SUCCEEDED(hr), "create xfb encode texture sampler");
    D3D::SetDebugObjectName(m_efbSampler, "xfb encoder texture sampler");
}
Example #28
0
   OpenGL::OpenGL(ID3D11Device* device, ID3D11DeviceContext* context)
   {
      s_instance = this;
      _orthoLeft = 0;
      _orthoRight = 0;
      _orthoBottom = 0;
      _orthoTop = 0;

      _device = device;
      _context = context;
      _vertexBuffer = NULL;
      _currentTextureId = 0;
      _enableTexture2D = false;
      _batchCurrentTextureId = 0;
      _batchEnableTexture2D = false;
      _loadingComplete = false;
      _vertexBuilder = new VertexBuilder();
      _maxVertices = MaxBatchVertices;
      _firstDrawInFrame = false;

      _currentBatchVertex = 0;

      _enableScissoring = false;
      _scissorRect.left = 0;
      _scissorRect.right = 0;
      _scissorRect.top = 0;
      _scissorRect.bottom = 0;

      _vertexShader = NULL;
      _pixelShaderTexture = NULL;
      _pixelShaderColor = NULL;

      auto vsize = sizeof (this->_batchVertices);

      // Asynchronously load the vertex and pixel shaders
      auto loadVSTask = ReadDataAsync("OpenGLVS.cso");
      auto loadPSColorTask = ReadDataAsync("OpenGLColorPS.cso");
      auto loadPSTextureTask = ReadDataAsync("OpenGLTexturePS.cso");

      auto createVSTask = loadVSTask.then([this](ByteArray ba) {
         auto bytecodeVS = ba.data;
         ThrowIfFailed(
            _device->CreateVertexShader(
            bytecodeVS->Data,
            bytecodeVS->Length,
            nullptr,
            &_vertexShader
            )
            );

         const D3D11_INPUT_ELEMENT_DESC vertexDesc[] = 
         {
            { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT,    0, 0,                            D3D11_INPUT_PER_VERTEX_DATA, 0 },
            { "COLOR",    0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
            { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT,       0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
         }; 

         ThrowIfFailed(
            _device->CreateInputLayout(
            vertexDesc,
            ARRAYSIZE(vertexDesc),
            bytecodeVS->Data,
            bytecodeVS->Length,
            &_inputLayout
            )
            );
      });

      auto createPSColorTask = loadPSColorTask.then([this](ByteArray ba) {
         auto bytecodePS = ba.data;
         ThrowIfFailed(
            _device->CreatePixelShader(
            bytecodePS->Data,
            bytecodePS->Length,
            nullptr,
            &_pixelShaderColor
            )
            );
      });

      auto createPSTextureTask = loadPSTextureTask.then([this](ByteArray ba) {
         auto bytecodePS = ba.data;
         ThrowIfFailed(
            _device->CreatePixelShader(
            bytecodePS->Data,
            bytecodePS->Length,
            nullptr,
            &_pixelShaderTexture
            )
            );

         ThrowIfFailed(
            _device->CreateBuffer(
            &CD3D11_BUFFER_DESC(sizeof(ModelViewProjectionConstantBuffer), D3D11_BIND_CONSTANT_BUFFER),
            nullptr,
            &_constantBuffer
            ));
      });

      createPSTextureTask.then([this] () {
         _loadingComplete = true;
      });

      ZeroMemory(&_rasterizerDesc, sizeof(_rasterizerDesc));
      _rasterizerDesc.FillMode = D3D11_FILL_MODE::D3D11_FILL_SOLID;
      _rasterizerDesc.CullMode = D3D11_CULL_MODE::D3D11_CULL_NONE;
      _rasterizerDesc.FrontCounterClockwise = true;
      _rasterizerDesc.DepthBias = 0;
      _rasterizerDesc.SlopeScaledDepthBias = 0.f;
      _rasterizerDesc.DepthBiasClamp = 0.f;
      _rasterizerDesc.DepthClipEnable = true;
      _rasterizerDesc.ScissorEnable = false;
      _rasterizerDesc.MultisampleEnable = false;
      _rasterizerDesc.AntialiasedLineEnable = false;
      ID3D11RasterizerState* rasterizerState;
      _device->CreateRasterizerState(&_rasterizerDesc, &rasterizerState);
      _context->RSSetState(rasterizerState);

      // Push an identity matrix on the stack to start with
      DirectX::XMFLOAT4X4* matrix = new DirectX::XMFLOAT4X4();
      auto identity = DirectX::XMMatrixIdentity();
      DirectX::XMStoreFloat4x4(matrix, identity);
      _matrices.push(matrix);
   }
Example #29
0
namespace DX11
{

static std::unique_ptr<TextureEncoder> g_encoder;
const size_t MAX_COPY_BUFFERS = 32;
ID3D11Buffer* efbcopycbuf[MAX_COPY_BUFFERS] = { 0 };

TextureCache::TCacheEntry::~TCacheEntry()
{
	texture->Release();
}

void TextureCache::TCacheEntry::Bind(unsigned int stage)
{
	D3D::stateman->SetTexture(stage, texture->GetSRV());
}

bool TextureCache::TCacheEntry::Save(const std::string& filename, unsigned int level)
{
	// TODO: Somehow implement this (D3DX11 doesn't support dumping individual LODs)
	static bool warn_once = true;
	if (level && warn_once)
	{
		WARN_LOG(VIDEO, "Dumping individual LOD not supported by D3D11 backend!");
		warn_once = false;
		return false;
	}

	ID3D11Texture2D* pNewTexture = nullptr;
	ID3D11Texture2D* pSurface = texture->GetTex();
	D3D11_TEXTURE2D_DESC desc;
	pSurface->GetDesc(&desc);

	desc.BindFlags = 0;
	desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
	desc.Usage = D3D11_USAGE_STAGING;

	HRESULT hr = D3D::device->CreateTexture2D(&desc, nullptr, &pNewTexture);

	bool saved_png = false;

	if (SUCCEEDED(hr) && pNewTexture)
	{
		D3D::context->CopyResource(pNewTexture, pSurface);

		D3D11_MAPPED_SUBRESOURCE map;
		hr = D3D::context->Map(pNewTexture, 0, D3D11_MAP_READ_WRITE, 0, &map);
		if (SUCCEEDED(hr))
		{
			saved_png = TextureToPng((u8*)map.pData, map.RowPitch, filename, desc.Width, desc.Height);
			D3D::context->Unmap(pNewTexture, 0);
		}
		SAFE_RELEASE(pNewTexture);
	}

	return saved_png;
}

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 TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height,
	unsigned int expanded_width, unsigned int level)
{
	unsigned int src_pitch = 4 * expanded_width;
	D3D::ReplaceRGBATexture2D(texture->GetTex(), TextureCache::temp, width, height, src_pitch, level, usage);
}

TextureCacheBase::TCacheEntryBase* TextureCache::CreateTexture(const TCacheEntryConfig& config)
{
	if (config.rendertarget)
	{
		return new TCacheEntry(config, D3DTexture2D::Create(config.width, config.height,
			(D3D11_BIND_FLAG)((int)D3D11_BIND_RENDER_TARGET | (int)D3D11_BIND_SHADER_RESOURCE),
			D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM, 1, config.layers));
	}
	else
	{
		D3D11_USAGE usage = D3D11_USAGE_DEFAULT;
		D3D11_CPU_ACCESS_FLAG cpu_access = (D3D11_CPU_ACCESS_FLAG)0;

		if (config.levels == 1)
		{
			usage = D3D11_USAGE_DYNAMIC;
			cpu_access = D3D11_CPU_ACCESS_WRITE;
		}

		const D3D11_TEXTURE2D_DESC texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM,
			config.width, config.height, 1, config.levels, D3D11_BIND_SHADER_RESOURCE, usage, cpu_access);

		ID3D11Texture2D *pTexture;
		const HRESULT hr = D3D::device->CreateTexture2D(&texdesc, nullptr, &pTexture);
		CHECK(SUCCEEDED(hr), "Create texture of the TextureCache");

		TCacheEntry* const entry = new TCacheEntry(config, new D3DTexture2D(pTexture, D3D11_BIND_SHADER_RESOURCE));
		entry->usage = usage;

		// TODO: better debug names
		D3D::SetDebugObjectName((ID3D11DeviceChild*)entry->texture->GetTex(), "a texture of the TextureCache");
		D3D::SetDebugObjectName((ID3D11DeviceChild*)entry->texture->GetSRV(), "shader resource view of a texture of the TextureCache");

		SAFE_RELEASE(pTexture);

		return entry;
	}
}

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 TextureCache::CopyEFB(u8* dst, u32 format, u32 native_width, u32 bytes_per_row, u32 num_blocks_y, u32 memory_stride,
	PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect,
	bool isIntensity, bool scaleByHalf)
{
	g_encoder->Encode(dst, format, native_width, bytes_per_row, num_blocks_y, memory_stride, srcFormat, srcRect, isIntensity, scaleByHalf);
}

const char palette_shader[] =
R"HLSL(
sampler samp0 : register(s0);
Texture2DArray Tex0 : register(t0);
Buffer<uint> Tex1 : register(t1);
uniform float Multiply;

uint Convert3To8(uint v)
{
	// Swizzle bits: 00000123 -> 12312312
	return (v << 5) | (v << 2) | (v >> 1);
}

uint Convert4To8(uint v)
{
	// Swizzle bits: 00001234 -> 12341234
	return (v << 4) | v;
}

uint Convert5To8(uint v)
{
	// Swizzle bits: 00012345 -> 12345123
	return (v << 3) | (v >> 2);
}

uint Convert6To8(uint v)
{
	// Swizzle bits: 00123456 -> 12345612
	return (v << 2) | (v >> 4);
}

float4 DecodePixel_RGB5A3(uint val)
{
	int r,g,b,a;
	if ((val&0x8000))
	{
		r=Convert5To8((val>>10) & 0x1f);
		g=Convert5To8((val>>5 ) & 0x1f);
		b=Convert5To8((val    ) & 0x1f);
		a=0xFF;
	}
	else
	{
		a=Convert3To8((val>>12) & 0x7);
		r=Convert4To8((val>>8 ) & 0xf);
		g=Convert4To8((val>>4 ) & 0xf);
		b=Convert4To8((val    ) & 0xf);
	}
	return float4(r, g, b, a) / 255;
}

float4 DecodePixel_RGB565(uint val)
{
	int r, g, b, a;
	r = Convert5To8((val >> 11) & 0x1f);
	g = Convert6To8((val >> 5) & 0x3f);
	b = Convert5To8((val) & 0x1f);
	a = 0xFF;
	return float4(r, g, b, a) / 255;
}

float4 DecodePixel_IA8(uint val)
{
	int i = val & 0xFF;
	int a = val >> 8;
	return float4(i, i, i, a) / 255;
}

void main(
	out float4 ocol0 : SV_Target,
	in float4 pos : SV_Position,
	in float3 uv0 : TEXCOORD0)
{
	uint src = round(Tex0.Sample(samp0,uv0) * Multiply).r;
	src = Tex1.Load(src);
	src = ((src << 8) & 0xFF00) | (src >> 8);
	ocol0 = DECODE(src);
}
)HLSL";

void TextureCache::ConvertTexture(TCacheEntryBase* entry, TCacheEntryBase* unconverted, void* palette, TlutFormat format)
{
	g_renderer->ResetAPIState();

	// stretch picture with increased internal resolution
	const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)unconverted->config.width, (float)unconverted->config.height);
	D3D::context->RSSetViewports(1, &vp);

	D3D11_BOX box{ 0, 0, 0, 512, 1, 1 };
	D3D::context->UpdateSubresource(palette_buf, 0, &box, palette, 0, 0);

	D3D::stateman->SetTexture(1, palette_buf_srv);

	// TODO: Add support for C14X2 format.  (Different multiplier, more palette entries.)
	float params[4] = { (unconverted->format & 0xf) == 0 ? 15.f : 255.f };
	D3D::context->UpdateSubresource(palette_uniform, 0, nullptr, &params, 0, 0);
	D3D::stateman->SetPixelConstants(palette_uniform);

	const D3D11_RECT sourcerect = CD3D11_RECT(0, 0, unconverted->config.width, unconverted->config.height);

	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(static_cast<TCacheEntry*>(entry)->texture->GetSRV());

	D3D::context->OMSetRenderTargets(1, &static_cast<TCacheEntry*>(entry)->texture->GetRTV(), nullptr);

	// Create texture copy
	D3D::drawShadedTexQuad(
		static_cast<TCacheEntry*>(unconverted)->texture->GetSRV(),
		&sourcerect, unconverted->config.width, unconverted->config.height,
		palette_pixel_shader[format],
		VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(),
		GeometryShaderCache::GetCopyGeometryShader());

	D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());

	g_renderer->RestoreAPIState();
}

ID3D11PixelShader *GetConvertShader(const char* Type)
{
	std::string shader = "#define DECODE DecodePixel_";
	shader.append(Type);
	shader.append("\n");
	shader.append(palette_shader);
	return D3D::CompileAndCreatePixelShader(shader);
}

TextureCache::TextureCache()
{
	// FIXME: Is it safe here?
	g_encoder = std::make_unique<PSTextureEncoder>();
	g_encoder->Init();

	palette_buf = nullptr;
	palette_buf_srv = nullptr;
	palette_uniform = nullptr;
	palette_pixel_shader[GX_TL_IA8] = GetConvertShader("IA8");
	palette_pixel_shader[GX_TL_RGB565] = GetConvertShader("RGB565");
	palette_pixel_shader[GX_TL_RGB5A3] = GetConvertShader("RGB5A3");
	auto lutBd = CD3D11_BUFFER_DESC(sizeof(u16) * 256, D3D11_BIND_SHADER_RESOURCE);
	HRESULT hr = D3D::device->CreateBuffer(&lutBd, nullptr, &palette_buf);
	CHECK(SUCCEEDED(hr), "create palette decoder lut buffer");
	D3D::SetDebugObjectName(palette_buf, "texture decoder lut buffer");
	// TODO: C14X2 format.
	auto outlutUavDesc = CD3D11_SHADER_RESOURCE_VIEW_DESC(palette_buf, DXGI_FORMAT_R16_UINT, 0, 256, 0);
	hr = D3D::device->CreateShaderResourceView(palette_buf, &outlutUavDesc, &palette_buf_srv);
	CHECK(SUCCEEDED(hr), "create palette decoder lut srv");
	D3D::SetDebugObjectName(palette_buf_srv, "texture decoder lut srv");
	const D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(16, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DEFAULT);
	hr = D3D::device->CreateBuffer(&cbdesc, nullptr, &palette_uniform);
	CHECK(SUCCEEDED(hr), "Create palette decoder constant buffer");
	D3D::SetDebugObjectName((ID3D11DeviceChild*)palette_uniform, "a constant buffer used in TextureCache::CopyRenderTargetToTexture");
}
Example #30
0
ConstantStreamBuffer::ConstantStreamBuffer(int size) : m_max_size(ROUND_UP(size, 256)), m_need_init(true)
{
	m_use_partial_buffer_update = D3D::SupportPartialContantBufferUpdate();
	D3D11_BUFFER_DESC desc = CD3D11_BUFFER_DESC(m_max_size, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
	device->CreateBuffer(&desc, nullptr, &m_buf);
}