Improve GL shader reflection to include Atomic bufs, SSBOs and images

This commit is contained in:
baldurk
2015-01-19 02:04:08 +00:00
parent 48f98ebdef
commit de6d93c47f
9 changed files with 818 additions and 390 deletions
+1 -1
View File
@@ -181,7 +181,7 @@ struct ShaderResource
bool32 IsSampler;
bool32 IsTexture;
bool32 IsSRV;
bool32 IsUAV;
bool32 IsReadWrite;
ShaderResourceType resType;
+1 -1
View File
@@ -397,7 +397,7 @@ void Serialiser::Serialise(const char *name, ShaderResource &el)
Serialise("", el.IsSampler);
Serialise("", el.IsTexture);
Serialise("", el.IsSRV);
Serialise("", el.IsUAV);
Serialise("", el.IsReadWrite);
Serialise("", el.name);
Serialise("", el.variableType);
Serialise("", el.bindPoint);
+6 -6
View File
@@ -877,12 +877,12 @@ ShaderReflection *MakeShaderReflection(DXBC::DXBCFile *dxbc)
r.type == DXBC::ShaderInputBind::TYPE_TEXTURE ||
r.type == DXBC::ShaderInputBind::TYPE_STRUCTURED ||
r.type == DXBC::ShaderInputBind::TYPE_BYTEADDRESS);
res.IsUAV = (r.type == DXBC::ShaderInputBind::TYPE_UAV_RWTYPED ||
r.type == DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED ||
r.type == DXBC::ShaderInputBind::TYPE_UAV_RWBYTEADDRESS ||
r.type == DXBC::ShaderInputBind::TYPE_UAV_APPEND_STRUCTURED ||
r.type == DXBC::ShaderInputBind::TYPE_UAV_CONSUME_STRUCTURED ||
r.type == DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED_WITH_COUNTER);
res.IsReadWrite = (r.type == DXBC::ShaderInputBind::TYPE_UAV_RWTYPED ||
r.type == DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED ||
r.type == DXBC::ShaderInputBind::TYPE_UAV_RWBYTEADDRESS ||
r.type == DXBC::ShaderInputBind::TYPE_UAV_APPEND_STRUCTURED ||
r.type == DXBC::ShaderInputBind::TYPE_UAV_CONSUME_STRUCTURED ||
r.type == DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED_WITH_COUNTER);
switch(r.dimension)
{
+82 -13
View File
@@ -783,7 +783,7 @@ void GLReplay::GetMapping(WrappedOpenGL &gl, GLuint curProg, int shadIdx, Shader
dummyReadback[i] = 0x6c7b8a9d;
#endif
GLenum refEnum[] = {
const GLenum refEnum[] = {
eGL_REFERENCED_BY_VERTEX_SHADER,
eGL_REFERENCED_BY_TESS_CONTROL_SHADER,
eGL_REFERENCED_BY_TESS_EVALUATION_SHADER,
@@ -795,31 +795,98 @@ void GLReplay::GetMapping(WrappedOpenGL &gl, GLuint curProg, int shadIdx, Shader
create_array_uninit(mapping.Resources, refl->Resources.count);
for(int32_t i=0; i < refl->Resources.count; i++)
{
if(refl->Resources.elems[i].IsSRV && refl->Resources.elems[i].IsTexture)
if(refl->Resources.elems[i].IsTexture)
{
// normal sampler or image load/store
GLint loc = gl.glGetUniformLocation(curProg, refl->Resources.elems[i].name.elems);
if(loc >= 0)
{
gl.glGetUniformiv(curProg, loc, dummyReadback);
mapping.Resources[i].bind = dummyReadback[0];
}
GLuint idx = 0;
idx = gl.glGetProgramResourceIndex(curProg, eGL_UNIFORM, refl->Resources.elems[i].name.elems);
if(idx == GL_INVALID_INDEX)
{
mapping.Resources[i].used = false;
}
else
{
GLint used = 0;
gl.glGetProgramResourceiv(curProg, eGL_UNIFORM, idx, 1, &refEnum[shadIdx], 1, NULL, &used);
mapping.Resources[i].used = (used != 0);
}
}
else if(refl->Resources.elems[i].IsReadWrite && !refl->Resources.elems[i].IsTexture)
{
if(refl->Resources.elems[i].variableType.descriptor.cols == 1 &&
refl->Resources.elems[i].variableType.descriptor.rows == 1 &&
refl->Resources.elems[i].variableType.descriptor.type == eVar_UInt)
{
// atomic uint
GLuint idx = gl.glGetProgramResourceIndex(curProg, eGL_UNIFORM, refl->Resources.elems[i].name.elems);
if(idx == GL_INVALID_INDEX)
{
mapping.Resources[i].bind = -1;
mapping.Resources[i].used = false;
}
else
{
GLenum prop = eGL_ATOMIC_COUNTER_BUFFER_INDEX;
GLuint atomicIndex;
gl.glGetProgramResourceiv(curProg, eGL_UNIFORM, idx, 1, &prop, 1, NULL, (GLint *)&atomicIndex);
if(atomicIndex == GL_INVALID_INDEX)
{
mapping.Resources[i].bind = -1;
mapping.Resources[i].used = false;
}
else
{
const GLenum atomicRefEnum[] = {
eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER,
eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER,
eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER,
eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER,
eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER,
eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER,
};
gl.glGetActiveAtomicCounterBufferiv(curProg, atomicIndex, eGL_ATOMIC_COUNTER_BUFFER_BINDING, &mapping.Resources[i].bind);
GLint used = 0;
gl.glGetActiveAtomicCounterBufferiv(curProg, atomicIndex, atomicRefEnum[shadIdx], &used);
mapping.Resources[i].used = (used != 0);
}
}
}
else
{
// shader storage buffer object
GLuint idx = gl.glGetProgramResourceIndex(curProg, eGL_SHADER_STORAGE_BLOCK, refl->Resources.elems[i].name.elems);
if(idx == GL_INVALID_INDEX)
{
mapping.Resources[i].bind = -1;
mapping.Resources[i].used = false;
}
else
{
GLenum prop = eGL_BUFFER_BINDING;
gl.glGetProgramResourceiv(curProg, eGL_SHADER_STORAGE_BLOCK, idx, 1, &prop, 1, NULL, &mapping.Resources[i].bind);
GLint used = 0;
gl.glGetProgramResourceiv(curProg, eGL_SHADER_STORAGE_BLOCK, idx, 1, &refEnum[shadIdx], 1, NULL, &used);
mapping.Resources[i].used = (used != 0);
}
}
}
else
{
mapping.Resources[i].bind = -1;
}
GLuint idx = gl.glGetProgramResourceIndex(curProg, eGL_UNIFORM, refl->Resources.elems[i].name.elems);
if(idx == GL_INVALID_INDEX)
{
mapping.Resources[i].used = false;
}
else
{
GLint used = 0;
gl.glGetProgramResourceiv(curProg, eGL_UNIFORM, idx, 1, &refEnum[shadIdx], 1, NULL, &used);
mapping.Resources[i].used = (used != 0);
}
}
create_array_uninit(mapping.ConstantBlocks, refl->ConstantBlocks.count);
@@ -1226,6 +1293,8 @@ void GLReplay::SavePipelineState()
for(int32_t r=0; r < refls[s]->Resources.count; r++)
{
if(refls[s]->Resources[r].IsReadWrite) continue;
// bindPoint is the uniform value for this sampler
if(mappings[s]->Resources[ refls[s]->Resources[r].bindPoint ].bind == unit)
{
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -344,7 +344,7 @@ namespace renderdoc
public bool IsSampler;
public bool IsTexture;
public bool IsSRV;
public bool IsUAV;
public bool IsReadWrite;
public ShaderResourceType resType;
@@ -848,7 +848,7 @@ namespace renderdocui.Windows.PipelineState
{
foreach (var bind in state.m_CS.ShaderDetails.Resources)
{
if (bind.IsUAV && bind.bindPoint == i)
if (bind.IsReadWrite && bind.bindPoint == i)
shaderInput = bind;
}
}
@@ -1162,7 +1162,7 @@ namespace renderdocui.Windows.PipelineState
{
foreach (var bind in state.m_PS.ShaderDetails.Resources)
{
if (bind.IsUAV && bind.bindPoint == i + state.m_OM.UAVStartSlot)
if (bind.IsReadWrite && bind.bindPoint == i + state.m_OM.UAVStartSlot)
shaderInput = bind;
}
}
@@ -1512,7 +1512,7 @@ namespace renderdocui.Windows.PipelineState
if(r.IsTexture)
continue;
if ( (r.IsSRV && !uav) || (r.IsUAV && uav) )
if ((r.IsSRV && !uav) || (r.IsReadWrite && uav))
{
if (r.bindPoint == bind)
{
@@ -1821,7 +1821,7 @@ namespace renderdocui.Windows.PipelineState
{
char regChar = 't';
if (res.IsUAV)
if (res.IsReadWrite)
{
hlsl += "RW";
regChar = 'u';
@@ -2367,7 +2367,7 @@ namespace renderdocui.Windows.PipelineState
{
foreach (var bind in refl.Resources)
{
if (bind.IsUAV && bind.bindPoint == i)
if (bind.IsReadWrite && bind.bindPoint == i)
shaderInput = bind;
}
}
+2 -2
View File
@@ -346,7 +346,7 @@ namespace renderdocui.Windows
Regex rgx = new Regex(needle);
disasm = rgx.Replace(disasm, replacement);
}
if (r.IsUAV)
if (r.IsReadWrite)
{
var needle = string.Format(", u{0}([^0-9])", r.bindPoint);
var replacement = string.Format(", {0}$1", r.name);
@@ -837,7 +837,7 @@ namespace renderdocui.Windows
var res = m_Stage.SRVs[slot.bindPoint];
if (slot.IsUAV)
if (slot.IsReadWrite)
{
if(m_Stage.stage == ShaderStageType.Pixel)
res = pipestate.m_OM.UAVs[slot.bindPoint - pipestate.m_OM.UAVStartSlot];
+1 -1
View File
@@ -891,7 +891,7 @@ namespace renderdocui.Windows
{
foreach (var bind in details.Resources)
{
if (mapping.Resources[bind.bindPoint].bind == i && bind.IsUAV)
if (mapping.Resources[bind.bindPoint].bind == i && bind.IsReadWrite)
{
bindName = "<" + bind.name + ">";
}