|
@@ -127,6 +127,12 @@ static ANKI_USE_RESULT Error getShaderInfo(const CString& str, ShaderType& type,
|
|
|
bit = ShaderTypeBit::FRAGMENT;
|
|
bit = ShaderTypeBit::FRAGMENT;
|
|
|
idx = 4;
|
|
idx = 4;
|
|
|
}
|
|
}
|
|
|
|
|
+ else if(str == "comp")
|
|
|
|
|
+ {
|
|
|
|
|
+ type = ShaderType::COMPUTE;
|
|
|
|
|
+ bit = ShaderTypeBit::COMPUTE;
|
|
|
|
|
+ idx = 5;
|
|
|
|
|
+ }
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
ANKI_RESOURCE_LOGE("Incorrect type %s", (str) ? &str[0] : "<empty string>");
|
|
ANKI_RESOURCE_LOGE("Incorrect type %s", (str) ? &str[0] : "<empty string>");
|
|
@@ -324,7 +330,7 @@ Error ShaderProgramResource::load(const ResourceFilename& filename)
|
|
|
StringListAuto globalsSrcList(getTempAllocator());
|
|
StringListAuto globalsSrcList(getTempAllocator());
|
|
|
StringListAuto definesSrcList(getTempAllocator());
|
|
StringListAuto definesSrcList(getTempAllocator());
|
|
|
ShaderTypeBit presentShaders = ShaderTypeBit::NONE;
|
|
ShaderTypeBit presentShaders = ShaderTypeBit::NONE;
|
|
|
- Array<CString, 5> shaderSources;
|
|
|
|
|
|
|
+ Array<CString, U(ShaderType::COUNT)> shaderSources;
|
|
|
ANKI_CHECK(shadersEl.getChildElement("shader", shaderEl));
|
|
ANKI_CHECK(shadersEl.getChildElement("shader", shaderEl));
|
|
|
do
|
|
do
|
|
|
{
|
|
{
|
|
@@ -348,6 +354,11 @@ Error ShaderProgramResource::load(const ResourceFilename& filename)
|
|
|
m_tessellation = true;
|
|
m_tessellation = true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if(!!(presentShaders & ShaderTypeBit::COMPUTE))
|
|
|
|
|
+ {
|
|
|
|
|
+ m_compute = true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// <inputs>
|
|
// <inputs>
|
|
|
XmlElement inputsEl;
|
|
XmlElement inputsEl;
|
|
|
ANKI_CHECK(shaderEl.getChildElementOptional("inputs", inputsEl));
|
|
ANKI_CHECK(shaderEl.getChildElementOptional("inputs", inputsEl));
|
|
@@ -375,16 +386,27 @@ Error ShaderProgramResource::load(const ResourceFilename& filename)
|
|
|
ANKI_ASSERT(inputVarCount == m_inputVars.getSize());
|
|
ANKI_ASSERT(inputVarCount == m_inputVars.getSize());
|
|
|
|
|
|
|
|
// Sanity checks
|
|
// Sanity checks
|
|
|
- if(!(presentShaders & ShaderTypeBit::VERTEX))
|
|
|
|
|
|
|
+ if(!!(presentShaders & ShaderTypeBit::COMPUTE))
|
|
|
{
|
|
{
|
|
|
- ANKI_RESOURCE_LOGE("Missing vertex shader");
|
|
|
|
|
- return ErrorCode::USER_DATA;
|
|
|
|
|
|
|
+ if(presentShaders != ShaderTypeBit::COMPUTE)
|
|
|
|
|
+ {
|
|
|
|
|
+ ANKI_RESOURCE_LOGE("Can't combine compute shader with other types of shaders");
|
|
|
|
|
+ return ErrorCode::USER_DATA;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- if(!(presentShaders & ShaderTypeBit::FRAGMENT))
|
|
|
|
|
|
|
+ else
|
|
|
{
|
|
{
|
|
|
- ANKI_RESOURCE_LOGE("Missing fragment shader");
|
|
|
|
|
- return ErrorCode::USER_DATA;
|
|
|
|
|
|
|
+ if(!(presentShaders & ShaderTypeBit::VERTEX))
|
|
|
|
|
+ {
|
|
|
|
|
+ ANKI_RESOURCE_LOGE("Missing vertex shader");
|
|
|
|
|
+ return ErrorCode::USER_DATA;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(!(presentShaders & ShaderTypeBit::FRAGMENT))
|
|
|
|
|
+ {
|
|
|
|
|
+ ANKI_RESOURCE_LOGE("Missing fragment shader");
|
|
|
|
|
+ return ErrorCode::USER_DATA;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Create sources
|
|
// Create sources
|
|
@@ -413,7 +435,7 @@ Error ShaderProgramResource::load(const ResourceFilename& filename)
|
|
|
definesSrcList.join("", backedDefinesSrc);
|
|
definesSrcList.join("", backedDefinesSrc);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- for(U s = 0; s < 5; ++s)
|
|
|
|
|
|
|
+ for(U s = 0; s < U(ShaderType::COUNT); ++s)
|
|
|
{
|
|
{
|
|
|
if(shaderSources[s])
|
|
if(shaderSources[s])
|
|
|
{
|
|
{
|
|
@@ -574,6 +596,13 @@ Error ShaderProgramResource::parseInputs(XmlElement& inputsEl,
|
|
|
ANKI_RESOURCE_LOGE("Input variable \"%s\" is instanced but there is no instanced mutator", &name[0]);
|
|
ANKI_RESOURCE_LOGE("Input variable \"%s\" is instanced but there is no instanced mutator", &name[0]);
|
|
|
return ErrorCode::USER_DATA;
|
|
return ErrorCode::USER_DATA;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ if(instanced && m_compute)
|
|
|
|
|
+ {
|
|
|
|
|
+ ANKI_RESOURCE_LOGE("Compute program can't be instanced");
|
|
|
|
|
+ return ErrorCode::USER_DATA;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
var.m_instanced = instanced != 0;
|
|
var.m_instanced = instanced != 0;
|
|
|
|
|
|
|
|
// Sanity checks
|
|
// Sanity checks
|
|
@@ -1022,8 +1051,8 @@ void ShaderProgramResource::initVariant(WeakArray<const ShaderProgramResourceMut
|
|
|
shaderHeaderSrc.join("", shaderHeader);
|
|
shaderHeaderSrc.join("", shaderHeader);
|
|
|
|
|
|
|
|
// Create the shaders and the program
|
|
// Create the shaders and the program
|
|
|
- Array<ShaderPtr, 5> shaders;
|
|
|
|
|
- for(ShaderType i = ShaderType::FIRST_GRAPHICS; i <= ShaderType::LAST_GRAPHICS; ++i)
|
|
|
|
|
|
|
+ Array<ShaderPtr, U(ShaderType::COUNT)> shaders;
|
|
|
|
|
+ for(ShaderType i = ShaderType::FIRST; i < ShaderType::COUNT; ++i)
|
|
|
{
|
|
{
|
|
|
if(!m_sources[i])
|
|
if(!m_sources[i])
|
|
|
{
|
|
{
|
|
@@ -1037,11 +1066,18 @@ void ShaderProgramResource::initVariant(WeakArray<const ShaderProgramResourceMut
|
|
|
shaders[i] = getManager().getGrManager().newInstance<Shader>(i, src.toCString());
|
|
shaders[i] = getManager().getGrManager().newInstance<Shader>(i, src.toCString());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- variant.m_prog = getManager().getGrManager().newInstance<ShaderProgram>(shaders[ShaderType::VERTEX],
|
|
|
|
|
- shaders[ShaderType::TESSELLATION_CONTROL],
|
|
|
|
|
- shaders[ShaderType::TESSELLATION_EVALUATION],
|
|
|
|
|
- shaders[ShaderType::GEOMETRY],
|
|
|
|
|
- shaders[ShaderType::FRAGMENT]);
|
|
|
|
|
|
|
+ if(!m_compute)
|
|
|
|
|
+ {
|
|
|
|
|
+ variant.m_prog = getManager().getGrManager().newInstance<ShaderProgram>(shaders[ShaderType::VERTEX],
|
|
|
|
|
+ shaders[ShaderType::TESSELLATION_CONTROL],
|
|
|
|
|
+ shaders[ShaderType::TESSELLATION_EVALUATION],
|
|
|
|
|
+ shaders[ShaderType::GEOMETRY],
|
|
|
|
|
+ shaders[ShaderType::FRAGMENT]);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ variant.m_prog = getManager().getGrManager().newInstance<ShaderProgram>(shaders[ShaderType::COMPUTE]);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
} // end namespace anki
|
|
} // end namespace anki
|