Esempio n. 1
0
bool WrappedOpenGL::Serialise_glCompileShader(GLuint shader)
{
	SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ShaderRes(GetCtx(), shader)));
	
	if(m_State == READING)
	{
		ResourceId liveId = GetResourceManager()->GetLiveID(id);

		auto &shadDetails = m_Shaders[liveId];

		bool pointSizeUsed = false, clipDistanceUsed = false;
		if(shadDetails.type == eGL_VERTEX_SHADER) CheckVertexOutputUses(shadDetails.sources, pointSizeUsed, clipDistanceUsed);

		GLuint sepProg = MakeSeparableShaderProgram(m_Real, shadDetails.type, shadDetails.sources, NULL);

		if(sepProg == 0)
		{
			RDCERR("Couldn't make separable program for shader via patching - functionality will be broken.");
		}
		else
		{
			shadDetails.prog = sepProg;
			MakeShaderReflection(m_Real, shadDetails.type, sepProg, shadDetails.reflection, pointSizeUsed, clipDistanceUsed);

			string s = CompileSPIRV(SPIRVShaderStage(ShaderIdx(shadDetails.type)), shadDetails.sources, shadDetails.spirv);
			if(!shadDetails.spirv.empty())
				DisassembleSPIRV(SPIRVShaderStage(ShaderIdx(shadDetails.type)), shadDetails.spirv, s);

			shadDetails.reflection.Disassembly = s;

			create_array_uninit(shadDetails.reflection.DebugInfo.files, shadDetails.sources.size());
			for(size_t i=0; i < shadDetails.sources.size(); i++)
			{
				shadDetails.reflection.DebugInfo.files[i].first = StringFormat::Fmt("source%u.glsl", (uint32_t)i);
				shadDetails.reflection.DebugInfo.files[i].second = shadDetails.sources[i];
			}
		}

		m_Real.glCompileShader(GetResourceManager()->GetLiveResource(id).name);
	}

	return true;
}
Esempio n. 2
0
void WrappedOpenGL::ShaderData::Compile(WrappedOpenGL &gl)
{
  bool pointSizeUsed = false, clipDistanceUsed = false;
  if(type == eGL_VERTEX_SHADER)
    CheckVertexOutputUses(sources, pointSizeUsed, clipDistanceUsed);

  GLuint sepProg = prog;

  if(sepProg == 0)
    sepProg = MakeSeparableShaderProgram(gl, type, sources, NULL);

  if(sepProg == 0)
  {
    RDCERR(
        "Couldn't make separable program for shader via patching - functionality will be broken.");
  }
  else
  {
    prog = sepProg;
    MakeShaderReflection(gl.GetHookset(), type, sepProg, reflection, pointSizeUsed, clipDistanceUsed);

    vector<uint32_t> spirvwords;

    string s = CompileSPIRV(SPIRVShaderStage(ShaderIdx(type)), sources, spirvwords);
    if(!spirvwords.empty())
      ParseSPIRV(&spirvwords.front(), spirvwords.size(), spirv);

    // for classic GL, entry point is always main
    reflection.Disassembly = spirv.Disassemble("main");

    create_array_uninit(reflection.DebugInfo.files, sources.size());
    for(size_t i = 0; i < sources.size(); i++)
    {
      reflection.DebugInfo.files[i].first = StringFormat::Fmt("source%u.glsl", (uint32_t)i);
      reflection.DebugInfo.files[i].second = sources[i];
    }
  }
}
Esempio n. 3
0
bool WrappedOpenGL::Serialise_glCreateShaderProgramv(GLuint program, GLenum type, GLsizei count, const GLchar *const*strings)
{
	SERIALISE_ELEMENT(GLenum, Type, type);
	SERIALISE_ELEMENT(int32_t, Count, count);
	SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program)));

	vector<string> src;

	for(int32_t i=0; i < Count; i++)
	{
		string s;
		if(m_State >= WRITING) s = strings[i];
		m_pSerialiser->SerialiseString("Source", s);
		if(m_State < WRITING) src.push_back(s);
	}

	if(m_State == READING)
	{
		char **sources = new char*[Count];
		
		for(int32_t i=0; i < Count; i++)
			sources[i] = &src[i][0];

		GLuint real = m_Real.glCreateShaderProgramv(Type, Count, sources);
		// we want a separate program that we can mess about with for making overlays
		// and relink without having to worry about restoring the 'real' program state.
		GLuint sepprog = MakeSeparableShaderProgram(m_Real, Type, src, NULL);

		delete[] sources;
		
		GLResource res = ProgramRes(GetCtx(), real);

		ResourceId liveId = m_ResourceManager->RegisterResource(res);
	
		auto &progDetails = m_Programs[liveId];
	
		progDetails.linked = true;
		progDetails.shaders.push_back(liveId);
		progDetails.stageShaders[ShaderIdx(Type)] = liveId;

		auto &shadDetails = m_Shaders[liveId];

		bool pointSizeUsed = false, clipDistanceUsed = false;
		if(Type == eGL_VERTEX_SHADER) CheckVertexOutputUses(src, pointSizeUsed, clipDistanceUsed);

		shadDetails.type = Type;
		shadDetails.sources.swap(src);
		shadDetails.prog = sepprog;
		MakeShaderReflection(m_Real, Type, real, shadDetails.reflection, pointSizeUsed, clipDistanceUsed);

		string s = CompileSPIRV(SPIRVShaderStage(ShaderIdx(shadDetails.type)), shadDetails.sources, shadDetails.spirv);
		if(!shadDetails.spirv.empty())
			DisassembleSPIRV(SPIRVShaderStage(ShaderIdx(shadDetails.type)), shadDetails.spirv, s);

		shadDetails.reflection.Disassembly = s;

		create_array_uninit(shadDetails.reflection.DebugInfo.files, shadDetails.sources.size());
		for(size_t i=0; i < shadDetails.sources.size(); i++)
		{
			shadDetails.reflection.DebugInfo.files[i].first = StringFormat::Fmt("source%u.glsl", (uint32_t)i);
			shadDetails.reflection.DebugInfo.files[i].second = shadDetails.sources[i];
		}

		GetResourceManager()->AddLiveResource(id, res);
	}

	return true;
}
Esempio n. 4
0
bool WrappedOpenGL::Serialise_glCompileShaderIncludeARB(GLuint shader, GLsizei count, const GLchar *const*path, const GLint *length)
{
	SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ShaderRes(GetCtx(), shader)));
	SERIALISE_ELEMENT(int32_t, Count, count);

	vector<string> paths;

	for(int32_t i=0; i < Count; i++)
	{
		string s;
		if(path && path[i])
			s = length > 0 ? string(path[i], path[i] + length[i]) : string(path[i]);
		
		m_pSerialiser->SerialiseString("path", s);

		if(m_State == READING)
			paths.push_back(s);
	}
	
	if(m_State == READING)
	{
		size_t numStrings = paths.size();

		const char **pathstrings = new const char*[numStrings];
		for(size_t i=0; i < numStrings; i++)
			pathstrings[i] = paths[i].c_str();

		ResourceId liveId = GetResourceManager()->GetLiveID(id);

		auto &shadDetails = m_Shaders[liveId];
		
		shadDetails.includepaths.clear();
		shadDetails.includepaths.reserve(Count);

		for(int32_t i=0; i < Count; i++)
			shadDetails.includepaths.push_back(pathstrings[i]);

		bool pointSizeUsed = false, clipDistanceUsed = false;
		if(shadDetails.type == eGL_VERTEX_SHADER) CheckVertexOutputUses(shadDetails.sources, pointSizeUsed, clipDistanceUsed);

		GLuint sepProg = MakeSeparableShaderProgram(m_Real, shadDetails.type, shadDetails.sources, &paths);

		if(sepProg == 0)
		{
			RDCERR("Couldn't make separable program for shader via patching - functionality will be broken.");
		}
		else
		{
			shadDetails.prog = sepProg;
			MakeShaderReflection(m_Real, shadDetails.type, sepProg, shadDetails.reflection, pointSizeUsed, clipDistanceUsed);
			
			string s = CompileSPIRV(SPIRVShaderStage(ShaderIdx(shadDetails.type)), shadDetails.sources, shadDetails.spirv);
			if(!shadDetails.spirv.empty())
				DisassembleSPIRV(SPIRVShaderStage(ShaderIdx(shadDetails.type)), shadDetails.spirv, s);

			shadDetails.reflection.Disassembly = s;

			create_array_uninit(shadDetails.reflection.DebugInfo.files, shadDetails.sources.size());
			for(size_t i=0; i < shadDetails.sources.size(); i++)
			{
				shadDetails.reflection.DebugInfo.files[i].first = StringFormat::Fmt("source%u.glsl", (uint32_t)i);
				shadDetails.reflection.DebugInfo.files[i].second = shadDetails.sources[i];
			}
		}

		m_Real.glCompileShaderIncludeARB(GetResourceManager()->GetLiveResource(id).name, Count, pathstrings, NULL);
		
		delete[] pathstrings;
	}

	return true;
}