Пример #1
0
void PixelShaderCache::Init()
{
	last_entry = NULL;

	//program used for clear screen
	{
		char pprog[3072];
		sprintf(pprog, "void main(\n"
							"out float4 ocol0 : COLOR0,\n"
							" in float4 incol0 : COLOR0){\n"
							"ocol0 = incol0;\n"
							"}\n");
		s_ClearProgram = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
	}

	int shaderModel = ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF);
	int maxConstants = (shaderModel < 3) ? 32 : ((shaderModel < 4) ? 224 : 65536);

	// other screen copy/convert programs
	for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++)
	{
		for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++)
		{
			for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++)
			{
				if(ssaaMode && !s_CopyProgram[copyMatrixType][depthType][ssaaMode-1]
				|| depthType && !s_CopyProgram[copyMatrixType][depthType-1][ssaaMode]
				|| copyMatrixType && !s_CopyProgram[copyMatrixType-1][depthType][ssaaMode])
				{
					// if it failed at a lower setting, it's going to fail here for the same reason it did there,
					// so skip this attempt to avoid duplicate error messages.
					s_CopyProgram[copyMatrixType][depthType][ssaaMode] = NULL;
				}
				else
				{
					s_CopyProgram[copyMatrixType][depthType][ssaaMode] = CreateCopyShader(copyMatrixType, depthType, ssaaMode);
				}
			}
		}
	}

	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, "%sdx9-%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();
}
Пример #2
0
void PixelShaderCache::Init()
{
	s_pixel_shaders_lock.unlock();
	for (u32 i = 0; i < PSRM_DEPTH_ONLY + 1; i++)
	{
		s_last_entry[i] = nullptr;
	}
	s_compiler = &HLSLAsyncCompiler::getInstance();

	//program used for clear screen
	{
		char pprog[3072];
		sprintf(pprog, "void main(\n"
			"out float4 ocol0 : COLOR0,\n"
			" in float4 incol0 : COLOR0){\n"
			"ocol0 = incol0;\n"
			"}\n");
		s_clear_program = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog));
	}

	int shaderModel = ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF);
	int maxConstants = (shaderModel < 3) ? 32 : ((shaderModel < 4) ? 224 : 65536);

	// other screen copy/convert programs
	for (int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++)
	{
		for (int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++)
		{
			for (int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++)
			{
				if (ssaaMode && !s_copy_program[copyMatrixType][depthType][ssaaMode - 1]
					|| depthType && !s_copy_program[copyMatrixType][depthType - 1][ssaaMode]
					|| copyMatrixType && !s_copy_program[copyMatrixType - 1][depthType][ssaaMode])
				{
					// if it failed at a lower setting, it's going to fail here for the same reason it did there,
					// so skip this attempt to avoid duplicate error messages.
					s_copy_program[copyMatrixType][depthType][ssaaMode] = NULL;
				}
				else
				{
					s_copy_program[copyMatrixType][depthType][ssaaMode] = CreateCopyShader(copyMatrixType, depthType, ssaaMode);
				}
			}
		}
	}

	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);

	pKey_t gameid = (pKey_t)GetMurmurHash3(reinterpret_cast<const u8*>(SConfig::GetInstance().m_strGameID.data()), (u32)SConfig::GetInstance().m_strGameID.size(), 0);
	s_pshaders = ObjectUsageProfiler<PixelShaderUid, pKey_t, PSCacheEntry, PixelShaderUid::ShaderUidHasher>::Create(
		gameid,
		PIXELSHADERGEN_UID_VERSION,
		"Ishiiruka.ps.dx9",
		StringFromFormat("%s.ps.dx9", SConfig::GetInstance().m_strGameID.c_str())
	);

	std::string cache_filename = StringFromFormat("%sIDX9-%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);

	if (g_ActiveConfig.bCompileShaderOnStartup)
	{
		std::vector<PixelShaderUid> shaders;
		size_t shader_count = 0;
		s_pshaders->ForEachMostUsedByCategory(gameid,
			[&](const PixelShaderUid& item, size_t total)
		{
			PixelShaderUid newitem = item;
			pixel_shader_uid_data& uid_data = newitem.GetUidData<pixel_shader_uid_data>();

			if (uid_data.render_mode == PSRM_DUAL_SOURCE_BLEND && !g_ActiveConfig.backend_info.bSupportsDualSourceBlend)
			{
				uid_data.render_mode = PSRM_DEFAULT;
				newitem.ClearHASH();
				newitem.CalculateUIDHash();
				CompilePShader(newitem, PIXEL_SHADER_RENDER_MODE::PSRM_DEFAULT, true);
				uid_data.render_mode = PSRM_ALPHA_PASS;
				uid_data.fog_proj = 0;
				uid_data.fog_RangeBaseEnabled = 0;
				newitem.ClearHASH();
				newitem.CalculateUIDHash();
				CompilePShader(newitem, PIXEL_SHADER_RENDER_MODE::PSRM_ALPHA_PASS, true);
			}
			else
			{
				newitem.ClearHASH();
				newitem.CalculateUIDHash();
				CompilePShader(newitem, PIXEL_SHADER_RENDER_MODE::PSRM_DEFAULT, true);
			}
			shader_count++;
			if ((shader_count & 7) == 0)
			{
				Host_UpdateTitle(StringFromFormat("Compiling Pixel Shaders %i %% (%i/%i)", (shader_count * 100) / total, shader_count, total));
				s_compiler->WaitForFinish();
			}
		},
			[](PSCacheEntry& entry)
		{
			return !entry.shader;
		}, true);
		s_compiler->WaitForFinish();
	}
}