| 5050 | } |
| 5051 | |
| 5052 | void ProgramGL::create(const ShaderGL& _vsh, const ShaderGL& _fsh) |
| 5053 | { |
| 5054 | m_id = glCreateProgram(); |
| 5055 | BX_TRACE("Program create: GL%d: GL%d, GL%d", m_id, _vsh.m_id, _fsh.m_id); |
| 5056 | |
| 5057 | const uint64_t id = (uint64_t(_vsh.m_hash)<<32) | _fsh.m_hash; |
| 5058 | const bool cached = s_renderGL->programFetchFromCache(m_id, id); |
| 5059 | |
| 5060 | if (!cached) |
| 5061 | { |
| 5062 | GLint linked = 0; |
| 5063 | if (0 != _vsh.m_id) |
| 5064 | { |
| 5065 | GL_CHECK(glAttachShader(m_id, _vsh.m_id) ); |
| 5066 | |
| 5067 | if (0 != _fsh.m_id) |
| 5068 | { |
| 5069 | GL_CHECK(glAttachShader(m_id, _fsh.m_id) ); |
| 5070 | } |
| 5071 | |
| 5072 | GL_CHECK(glLinkProgram(m_id) ); |
| 5073 | GL_CHECK(glGetProgramiv(m_id, GL_LINK_STATUS, &linked) ); |
| 5074 | |
| 5075 | if (0 == linked) |
| 5076 | { |
| 5077 | char log[1024]; |
| 5078 | GL_CHECK(glGetProgramInfoLog(m_id, sizeof(log), NULL, log) ); |
| 5079 | BX_TRACE("%d: %s", linked, log); |
| 5080 | } |
| 5081 | } |
| 5082 | |
| 5083 | if (0 == linked) |
| 5084 | { |
| 5085 | BX_WARN(0 != _vsh.m_id, "Invalid vertex/compute shader."); |
| 5086 | GL_CHECK(glDeleteProgram(m_id) ); |
| 5087 | m_usedCount = 0; |
| 5088 | m_id = 0; |
| 5089 | return; |
| 5090 | } |
| 5091 | |
| 5092 | s_renderGL->programCache(m_id, id); |
| 5093 | } |
| 5094 | |
| 5095 | init(); |
| 5096 | |
| 5097 | if (!cached |
| 5098 | && s_renderGL->m_workaround.m_detachShader) |
| 5099 | { |
| 5100 | // Must be after init, otherwise init might fail to lookup shader |
| 5101 | // info (NVIDIA Tegra 3 OpenGL ES 2.0 14.01003). |
| 5102 | GL_CHECK(glDetachShader(m_id, _vsh.m_id) ); |
| 5103 | |
| 5104 | if (0 != _fsh.m_id) |
| 5105 | { |
| 5106 | GL_CHECK(glDetachShader(m_id, _fsh.m_id) ); |
| 5107 | } |
| 5108 | } |
| 5109 | } |
no test coverage detected