Split 'Resources' shader array into readonly/readwrite arrays

* This is preparation for a following commit, might not work on its own
  (mostly untested - just compiling).
This commit is contained in:
baldurk
2016-02-07 18:46:39 +01:00
parent e51cf27321
commit 6051f0c500
14 changed files with 425 additions and 549 deletions
+4 -3
View File
@@ -181,7 +181,6 @@ struct ShaderResource
bool32 IsSampler;
bool32 IsTexture;
bool32 IsSRV;
bool32 IsReadWrite;
ShaderResourceType resType;
@@ -215,7 +214,8 @@ struct ShaderReflection
rdctype::array<ConstantBlock> ConstantBlocks; // sparse - index indicates bind point
rdctype::array<ShaderResource> Resources; // non-sparse, since bind points can overlap.
rdctype::array<ShaderResource> ReadOnlyResources; // non-sparse, since bind points can overlap.
rdctype::array<ShaderResource> ReadWriteResources; // non-sparse, since bind points can overlap.
// TODO expand this to encompass shader subroutines.
rdctype::array<rdctype::str> Interfaces;
@@ -233,5 +233,6 @@ struct ShaderBindpointMapping
{
rdctype::array<int> InputAttributes;
rdctype::array<BindpointMap> ConstantBlocks;
rdctype::array<BindpointMap> Resources;
rdctype::array<BindpointMap> ReadOnlyResources;
rdctype::array<BindpointMap> ReadWriteResources;
};
+13 -12
View File
@@ -122,9 +122,10 @@ void Serialiser::Serialise(const char *name, ShaderBindpointMapping &el)
{
Serialise("", el.InputAttributes);
Serialise("", el.ConstantBlocks);
Serialise("", el.Resources);
Serialise("", el.ReadOnlyResources);
Serialise("", el.ReadWriteResources);
SIZE_CHECK(ShaderBindpointMapping, 24);
SIZE_CHECK(ShaderBindpointMapping, 32);
}
template<>
@@ -188,13 +189,12 @@ void Serialiser::Serialise(const char *name, ShaderResource &el)
Serialise("", el.IsSampler);
Serialise("", el.IsTexture);
Serialise("", el.IsSRV);
Serialise("", el.IsReadWrite);
Serialise("", el.resType);
Serialise("", el.name);
Serialise("", el.variableType);
Serialise("", el.bindPoint);
SIZE_CHECK(ShaderResource, 68);
SIZE_CHECK(ShaderResource, 64);
}
template<>
@@ -213,11 +213,12 @@ void Serialiser::Serialise(const char *name, ShaderReflection &el)
Serialise("", el.ConstantBlocks);
Serialise("", el.Resources);
Serialise("", el.ReadOnlyResources);
Serialise("", el.ReadWriteResources);
Serialise("", el.Interfaces);
SIZE_CHECK(ShaderReflection, 84);
SIZE_CHECK(ShaderReflection, 92);
}
template<>
@@ -368,7 +369,7 @@ void Serialiser::Serialise(const char *name, D3D11PipelineState::ShaderStage &el
Serialise("", el.ConstantBuffers);
Serialise("", el.ClassInstances);
SIZE_CHECK(D3D11PipelineState::ShaderStage, 96);
SIZE_CHECK(D3D11PipelineState::ShaderStage, 104);
}
template<>
@@ -463,7 +464,7 @@ void Serialiser::Serialise(const char *name, D3D11PipelineState &el)
Serialise("", el.m_RS);
Serialise("", el.m_OM);
SIZE_CHECK(D3D11PipelineState, 1000);
SIZE_CHECK(D3D11PipelineState, 1040);
}
#pragma endregion D3D11 pipeline state
@@ -506,7 +507,7 @@ void Serialiser::Serialise(const char *name, GLPipelineState::ShaderStage &el)
if(m_Mode == READING)
el.ShaderDetails = NULL;
SIZE_CHECK(GLPipelineState::ShaderStage, 48);
SIZE_CHECK(GLPipelineState::ShaderStage, 56);
}
template<>
@@ -686,7 +687,7 @@ void Serialiser::Serialise(const char *name, GLPipelineState &el)
Serialise("", el.m_Hints);
SIZE_CHECK(GLPipelineState, 984);
SIZE_CHECK(GLPipelineState, 1032);
}
#pragma endregion OpenGL pipeline state
@@ -761,7 +762,7 @@ void Serialiser::Serialise(const char *name, VulkanPipelineState::ShaderStage &e
if(m_Mode == READING)
el.ShaderDetails = NULL;
SIZE_CHECK(VulkanPipelineState::ShaderStage, 56);
SIZE_CHECK(VulkanPipelineState::ShaderStage, 64);
}
template<>
@@ -881,7 +882,7 @@ void Serialiser::Serialise(const char *name, VulkanPipelineState &el)
Serialise("", el.DS);
Serialise("", el.Pass);
SIZE_CHECK(VulkanPipelineState, 744);
SIZE_CHECK(VulkanPipelineState, 792);
}
#pragma endregion Vulkan pipeline state
+31 -8
View File
@@ -974,13 +974,33 @@ ShaderReflection *MakeShaderReflection(DXBC::DXBCFile *dxbc)
}
}
int numResources = 0;
for(size_t i=0; i < dxbc->m_Resources.size(); i++)
if(dxbc->m_Resources[i].type != DXBC::ShaderInputBind::TYPE_CBUFFER)
numResources++;
int numRWResources = 0;
int numROResources = 0;
create_array_uninit(ret->Resources, numResources);
int32_t idx=0;
for(size_t i=0; i < dxbc->m_Resources.size(); i++)
{
const auto &r = dxbc->m_Resources[i];
if(r.type != DXBC::ShaderInputBind::TYPE_CBUFFER)
{
bool 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);
if(IsReadWrite)
numRWResources++;
else
numROResources++;
}
}
create_array_uninit(ret->ReadWriteResources, numRWResources);
create_array_uninit(ret->ReadOnlyResources, numROResources);
int32_t rwidx = 0, roidx = 0;
for(size_t i=0; i < dxbc->m_Resources.size(); i++)
{
const auto &r = dxbc->m_Resources[i];
@@ -1001,7 +1021,7 @@ ShaderReflection *MakeShaderReflection(DXBC::DXBCFile *dxbc)
r.type == DXBC::ShaderInputBind::TYPE_TEXTURE ||
r.type == DXBC::ShaderInputBind::TYPE_STRUCTURED ||
r.type == DXBC::ShaderInputBind::TYPE_BYTEADDRESS);
res.IsReadWrite = (r.type == DXBC::ShaderInputBind::TYPE_UAV_RWTYPED ||
bool 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 ||
@@ -1088,7 +1108,10 @@ ShaderReflection *MakeShaderReflection(DXBC::DXBCFile *dxbc)
}
}
ret->Resources[idx++] = res;
if(IsReadWrite)
ret->ReadWriteResources[rwidx++] = res;
else
ret->ReadOnlyResources[roidx++] = res;
}
uint32_t numInterfaces = 0;
+14 -5
View File
@@ -534,13 +534,22 @@ D3D11PipelineState D3D11Replay::MakePipelineState()
dst.BindpointMapping.ConstantBlocks[i].arraySize = 1;
}
create_array_uninit(dst.BindpointMapping.Resources, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT);
create_array_uninit(dst.BindpointMapping.ReadOnlyResources, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT);
for(int32_t s=0; s < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; s++)
{
dst.BindpointMapping.Resources[s].bindset = 0;
dst.BindpointMapping.Resources[s].bind = s;
dst.BindpointMapping.Resources[s].used = true;
dst.BindpointMapping.Resources[i].arraySize = 1;
dst.BindpointMapping.ReadOnlyResources[s].bindset = 0;
dst.BindpointMapping.ReadOnlyResources[s].bind = s;
dst.BindpointMapping.ReadOnlyResources[s].used = true;
dst.BindpointMapping.ReadOnlyResources[i].arraySize = 1;
}
create_array_uninit(dst.BindpointMapping.ReadWriteResources, D3D11_1_UAV_SLOT_COUNT);
for(int32_t s=0; s < D3D11_1_UAV_SLOT_COUNT; s++)
{
dst.BindpointMapping.ReadWriteResources[s].bindset = 0;
dst.BindpointMapping.ReadWriteResources[s].bind = s;
dst.BindpointMapping.ReadWriteResources[s].used = true;
dst.BindpointMapping.ReadWriteResources[i].arraySize = 1;
}
create_array_uninit(dst.ConstantBuffers, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
+21 -20
View File
@@ -4173,39 +4173,40 @@ void WrappedOpenGL::AddUsage(FetchDrawcall d)
m_ResourceUses[rm->GetID(BufferRes(ctx, rs.UniformBinding[bind].name))].push_back(cb);
}
for(int32_t r=0; r < refl[i]->Resources.count; r++)
for(int32_t r=0; r < refl[i]->ReadWriteResources.count; r++)
{
int32_t bind = mapping[i].Resources[ refl[i]->Resources[r].bindPoint ].bind;
int32_t bind = mapping[i].ReadWriteResources[ refl[i]->ReadWriteResources[r].bindPoint ].bind;
if(refl[i]->Resources[r].IsReadWrite)
if(refl[i]->ReadWriteResources[r].IsTexture)
{
if(refl[i]->Resources[r].IsTexture)
if(rs.Images[bind].name)
m_ResourceUses[rm->GetID(TextureRes(ctx, rs.Images[bind].name))].push_back(rw);
}
else
{
if(refl[i]->ReadWriteResources[r].variableType.descriptor.cols == 1 &&
refl[i]->ReadWriteResources[r].variableType.descriptor.rows == 1 &&
refl[i]->ReadWriteResources[r].variableType.descriptor.type == eVar_UInt)
{
if(rs.Images[bind].name)
m_ResourceUses[rm->GetID(TextureRes(ctx, rs.UniformBinding[bind].name))].push_back(rw);
if(rs.AtomicCounter[bind].name)
m_ResourceUses[rm->GetID(BufferRes(ctx, rs.AtomicCounter[bind].name))].push_back(rw);
}
else
{
if(refl[i]->Resources[r].variableType.descriptor.cols == 1 &&
refl[i]->Resources[r].variableType.descriptor.rows == 1 &&
refl[i]->Resources[r].variableType.descriptor.type == eVar_UInt)
{
if(rs.AtomicCounter[bind].name)
m_ResourceUses[rm->GetID(BufferRes(ctx, rs.AtomicCounter[bind].name))].push_back(rw);
}
else
{
if(rs.ShaderStorage[bind].name)
m_ResourceUses[rm->GetID(BufferRes(ctx, rs.ShaderStorage[bind].name))].push_back(rw);
}
if(rs.ShaderStorage[bind].name)
m_ResourceUses[rm->GetID(BufferRes(ctx, rs.ShaderStorage[bind].name))].push_back(rw);
}
continue;
}
}
for(int32_t r=0; r < refl[i]->ReadOnlyResources.count; r++)
{
int32_t bind = mapping[i].ReadOnlyResources[ refl[i]->ReadOnlyResources[r].bindPoint ].bind;
uint32_t *texList = NULL;
int32_t listSize = 0;
switch(refl[i]->Resources[r].resType)
switch(refl[i]->ReadOnlyResources[r].resType)
{
case eResType_None:
texList = NULL;
+7 -8
View File
@@ -1021,7 +1021,8 @@ void GLReplay::SavePipelineState()
stages[i]->Shader = ResourceId();
stages[i]->ShaderDetails = NULL;
stages[i]->BindpointMapping.ConstantBlocks.Delete();
stages[i]->BindpointMapping.Resources.Delete();
stages[i]->BindpointMapping.ReadOnlyResources.Delete();
stages[i]->BindpointMapping.ReadWriteResources.Delete();
}
if(curProg == 0)
@@ -1142,19 +1143,17 @@ void GLReplay::SavePipelineState()
{
if(refls[s] == NULL) continue;
for(int32_t r=0; r < refls[s]->Resources.count; r++)
for(int32_t r=0; r < refls[s]->ReadOnlyResources.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)
if(mappings[s]->ReadOnlyResources[ refls[s]->ReadOnlyResources[r].bindPoint ].bind == unit)
{
GLenum t = eGL_NONE;
if(strstr(refls[s]->Resources[r].variableType.descriptor.name.elems, "Shadow"))
if(strstr(refls[s]->ReadOnlyResources[r].variableType.descriptor.name.elems, "Shadow"))
shadow = true;
switch(refls[s]->Resources[r].resType)
switch(refls[s]->ReadOnlyResources[r].resType)
{
case eResType_None:
target = eGL_NONE;
@@ -1197,7 +1196,7 @@ void GLReplay::SavePipelineState()
if(target != eGL_NONE)
t = TextureBinding(target);
resType = refls[s]->Resources[r].resType;
resType = refls[s]->ReadOnlyResources[r].resType;
if(binding == eGL_NONE)
{
+138 -85
View File
@@ -783,7 +783,7 @@ void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg,
RDCEraseEl(refl.DispatchThreadsDimension);
}
vector<ShaderResource> resources;
vector<ShaderResource> roresources, rwresources;
GLint numUniforms = 0;
gl.glGetProgramInterfaceiv(sepProg, eGL_UNIFORM, eGL_ACTIVE_RESOURCES, &numUniforms);
@@ -798,17 +798,17 @@ void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg,
{
GLint values[numProps];
gl.glGetProgramResourceiv(sepProg, eGL_UNIFORM, u, numProps, resProps, numProps, NULL, values);
bool IsReadWrite = false;
ShaderResource res;
res.IsSampler = false; // no separate sampler objects in GL
res.IsSRV = true;
res.IsTexture = true;
res.IsReadWrite = false;
res.variableType.descriptor.rows = 1;
res.variableType.descriptor.cols = 4;
res.variableType.descriptor.elements = 0;
res.variableType.descriptor.rowMajorStorage = false;
res.bindPoint = (int32_t)resources.size();
// float samplers
if(values[0] == eGL_SAMPLER_BUFFER)
@@ -1053,88 +1053,88 @@ void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg,
res.resType = eResType_Buffer;
res.variableType.descriptor.name = "imageBuffer";
res.variableType.descriptor.type = eVar_Float;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_IMAGE_1D)
{
res.resType = eResType_Texture1D;
res.variableType.descriptor.name = "image1D";
res.variableType.descriptor.type = eVar_Float;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_IMAGE_1D_ARRAY)
{
res.resType = eResType_Texture1DArray;
res.variableType.descriptor.name = "image1DArray";
res.variableType.descriptor.type = eVar_Float;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_IMAGE_2D)
{
res.resType = eResType_Texture2D;
res.variableType.descriptor.name = "image2D";
res.variableType.descriptor.type = eVar_Float;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_IMAGE_2D_ARRAY)
{
res.resType = eResType_Texture2DArray;
res.variableType.descriptor.name = "image2DArray";
res.variableType.descriptor.type = eVar_Float;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_IMAGE_2D_RECT)
{
res.resType = eResType_TextureRect;
res.variableType.descriptor.name = "image2DRect";
res.variableType.descriptor.type = eVar_Float;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_IMAGE_3D)
{
res.resType = eResType_Texture3D;
res.variableType.descriptor.name = "image3D";
res.variableType.descriptor.type = eVar_Float;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_IMAGE_CUBE)
{
res.resType = eResType_TextureCube;
res.variableType.descriptor.name = "imageCube";
res.variableType.descriptor.type = eVar_Float;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_IMAGE_CUBE_MAP_ARRAY)
{
res.resType = eResType_TextureCubeArray;
res.variableType.descriptor.name = "imageCubeArray";
res.variableType.descriptor.type = eVar_Float;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_IMAGE_2D_MULTISAMPLE)
{
res.resType = eResType_Texture2DMS;
res.variableType.descriptor.name = "image2DMS";
res.variableType.descriptor.type = eVar_Float;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_IMAGE_2D_MULTISAMPLE_ARRAY)
{
res.resType = eResType_Texture2DMSArray;
res.variableType.descriptor.name = "image2DMSArray";
res.variableType.descriptor.type = eVar_Float;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
// int images
else if(values[0] == eGL_INT_IMAGE_BUFFER)
@@ -1142,88 +1142,88 @@ void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg,
res.resType = eResType_Buffer;
res.variableType.descriptor.name = "iimageBuffer";
res.variableType.descriptor.type = eVar_Int;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_INT_IMAGE_1D)
{
res.resType = eResType_Texture1D;
res.variableType.descriptor.name = "iimage1D";
res.variableType.descriptor.type = eVar_Int;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_INT_IMAGE_1D_ARRAY)
{
res.resType = eResType_Texture1DArray;
res.variableType.descriptor.name = "iimage1DArray";
res.variableType.descriptor.type = eVar_Int;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_INT_IMAGE_2D)
{
res.resType = eResType_Texture2D;
res.variableType.descriptor.name = "iimage2D";
res.variableType.descriptor.type = eVar_Int;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_INT_IMAGE_2D_ARRAY)
{
res.resType = eResType_Texture2DArray;
res.variableType.descriptor.name = "iimage2DArray";
res.variableType.descriptor.type = eVar_Int;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_INT_IMAGE_2D_RECT)
{
res.resType = eResType_TextureRect;
res.variableType.descriptor.name = "iimage2DRect";
res.variableType.descriptor.type = eVar_Int;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_INT_IMAGE_3D)
{
res.resType = eResType_Texture3D;
res.variableType.descriptor.name = "iimage3D";
res.variableType.descriptor.type = eVar_Int;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_INT_IMAGE_CUBE)
{
res.resType = eResType_TextureCube;
res.variableType.descriptor.name = "iimageCube";
res.variableType.descriptor.type = eVar_Int;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_INT_IMAGE_CUBE_MAP_ARRAY)
{
res.resType = eResType_TextureCubeArray;
res.variableType.descriptor.name = "iimageCubeArray";
res.variableType.descriptor.type = eVar_Int;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_INT_IMAGE_2D_MULTISAMPLE)
{
res.resType = eResType_Texture2DMS;
res.variableType.descriptor.name = "iimage2DMS";
res.variableType.descriptor.type = eVar_Int;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_INT_IMAGE_2D_MULTISAMPLE_ARRAY)
{
res.resType = eResType_Texture2DMSArray;
res.variableType.descriptor.name = "iimage2DMSArray";
res.variableType.descriptor.type = eVar_Int;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
// unsigned int images
else if(values[0] == eGL_UNSIGNED_INT_IMAGE_BUFFER)
@@ -1231,88 +1231,88 @@ void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg,
res.resType = eResType_Buffer;
res.variableType.descriptor.name = "uimageBuffer";
res.variableType.descriptor.type = eVar_UInt;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_UNSIGNED_INT_IMAGE_1D)
{
res.resType = eResType_Texture1D;
res.variableType.descriptor.name = "uimage1D";
res.variableType.descriptor.type = eVar_UInt;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_UNSIGNED_INT_IMAGE_1D_ARRAY)
{
res.resType = eResType_Texture1DArray;
res.variableType.descriptor.name = "uimage1DArray";
res.variableType.descriptor.type = eVar_UInt;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_UNSIGNED_INT_IMAGE_2D)
{
res.resType = eResType_Texture2D;
res.variableType.descriptor.name = "uimage2D";
res.variableType.descriptor.type = eVar_UInt;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_UNSIGNED_INT_IMAGE_2D_ARRAY)
{
res.resType = eResType_Texture2DArray;
res.variableType.descriptor.name = "uimage2DArray";
res.variableType.descriptor.type = eVar_UInt;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_UNSIGNED_INT_IMAGE_2D_RECT)
{
res.resType = eResType_TextureRect;
res.variableType.descriptor.name = "uimage2DRect";
res.variableType.descriptor.type = eVar_UInt;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_UNSIGNED_INT_IMAGE_3D)
{
res.resType = eResType_Texture3D;
res.variableType.descriptor.name = "uimage3D";
res.variableType.descriptor.type = eVar_UInt;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_UNSIGNED_INT_IMAGE_CUBE)
{
res.resType = eResType_TextureCube;
res.variableType.descriptor.name = "uimageCube";
res.variableType.descriptor.type = eVar_UInt;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY)
{
res.resType = eResType_TextureCubeArray;
res.variableType.descriptor.name = "uimageCubeArray";
res.variableType.descriptor.type = eVar_UInt;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE)
{
res.resType = eResType_Texture2DMS;
res.variableType.descriptor.name = "uimage2DMS";
res.variableType.descriptor.type = eVar_UInt;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
else if(values[0] == eGL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY)
{
res.resType = eResType_Texture2DMSArray;
res.variableType.descriptor.name = "uimage2DMSArray";
res.variableType.descriptor.type = eVar_UInt;
res.IsReadWrite = true;
res.IsSRV = false;
IsReadWrite = true;
}
// atomic counter
else if(values[0] == eGL_UNSIGNED_INT_ATOMIC_COUNTER)
@@ -1320,10 +1320,10 @@ void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg,
res.resType = eResType_Buffer;
res.variableType.descriptor.name = "atomic_uint";
res.variableType.descriptor.type = eVar_UInt;
res.IsReadWrite = true;
res.IsSRV = false;
res.IsTexture = false;
res.variableType.descriptor.cols = 1;
IsReadWrite = true;
}
else
{
@@ -1339,7 +1339,10 @@ void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg,
res.name = name;
resources.push_back(res);
vector<ShaderResource> &reslist = (IsReadWrite ? rwresources : roresources);
res.bindPoint = (int32_t)reslist.size();
reslist.push_back(res);
// array of samplers
if(values[4] > 1)
@@ -1349,10 +1352,10 @@ void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg,
{
string arrname = StringFormat::Fmt("%s[%d]", name.c_str(), i);
res.bindPoint = (int32_t)resources.size();
res.bindPoint = (int32_t)reslist.size();
res.name = arrname;
resources.push_back(res);
reslist.push_back(res);
}
}
}
@@ -1377,7 +1380,6 @@ void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg,
res.IsSampler = false;
res.IsSRV = false;
res.IsTexture = false;
res.IsReadWrite = true;
res.resType = eResType_Buffer;
res.variableType.descriptor.rows = 0;
res.variableType.descriptor.cols = 0;
@@ -1385,13 +1387,13 @@ void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg,
res.variableType.descriptor.rowMajorStorage = false;
res.variableType.descriptor.name = "buffer";
res.variableType.descriptor.type = eVar_UInt;
res.bindPoint = (int32_t)resources.size();
res.bindPoint = (int32_t)rwresources.size();
res.name = nm;
propName = eGL_NUM_ACTIVE_VARIABLES;
gl.glGetProgramResourceiv(sepProg, eGL_SHADER_STORAGE_BLOCK, u, 1, &propName, 1, NULL, (GLint *)&res.variableType.descriptor.elements);
resources.push_back(res);
rwresources.push_back(res);
ssbos.push_back(res.bindPoint);
ssboMembers += res.variableType.descriptor.elements;
@@ -1410,7 +1412,7 @@ void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg,
for(size_t ssbo=0; ssbo < ssbos.size(); ssbo++)
{
sort(members[ssbo]);
copy(resources[ ssbos[ssbo] ].variableType.members, members[ssbo]);
copy(rwresources[ ssbos[ssbo] ].variableType.members, members[ssbo]);
}
delete[] members;
@@ -1772,7 +1774,8 @@ void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg,
// TODO: fill in Interfaces with shader subroutines?
refl.Resources = resources;
refl.ReadOnlyResources = roresources;
refl.ReadWriteResources = rwresources;
refl.ConstantBlocks = cbuffers;
}
@@ -1795,26 +1798,26 @@ void GetBindpointMapping(const GLHookSet &gl, GLuint curProg, int shadIdx, Shade
eGL_REFERENCED_BY_COMPUTE_SHADER,
};
int32_t numResources = refl ? refl->Resources.count : 0;
int32_t numResources = refl ? refl->ReadOnlyResources.count : 0;
create_array_uninit(mapping.Resources, numResources);
create_array_uninit(mapping.ReadOnlyResources, numResources);
for(int32_t i=0; i < numResources; i++)
{
if(refl->Resources.elems[i].IsTexture)
if(refl->ReadOnlyResources.elems[i].IsTexture)
{
// normal sampler or image load/store
GLint loc = gl.glGetUniformLocation(curProg, refl->Resources.elems[i].name.elems);
GLint loc = gl.glGetUniformLocation(curProg, refl->ReadOnlyResources.elems[i].name.elems);
if(loc >= 0)
{
gl.glGetUniformiv(curProg, loc, dummyReadback);
mapping.Resources[i].bindset = 0;
mapping.Resources[i].bind = dummyReadback[0];
mapping.Resources[i].arraySize = 1;
mapping.ReadOnlyResources[i].bindset = 0;
mapping.ReadOnlyResources[i].bind = dummyReadback[0];
mapping.ReadOnlyResources[i].arraySize = 1;
}
// handle sampler arrays, use the base name
string name = refl->Resources.elems[i].name.elems;
string name = refl->ReadOnlyResources.elems[i].name.elems;
if(name.back() == ']')
{
do
@@ -1829,30 +1832,80 @@ void GetBindpointMapping(const GLHookSet &gl, GLuint curProg, int shadIdx, Shade
if(idx == GL_INVALID_INDEX)
{
mapping.Resources[i].used = false;
mapping.ReadOnlyResources[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);
mapping.ReadOnlyResources[i].used = (used != 0);
}
}
else if(refl->Resources.elems[i].IsReadWrite && !refl->Resources.elems[i].IsTexture)
else
{
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)
mapping.ReadOnlyResources[i].bindset = -1;
mapping.ReadOnlyResources[i].bind = -1;
mapping.ReadOnlyResources[i].used = false;
mapping.ReadOnlyResources[i].arraySize = 1;
}
}
create_array_uninit(mapping.ReadWriteResources, refl->ReadWriteResources.count);
for(int32_t i=0; i < refl->ReadWriteResources.count; i++)
{
if(refl->ReadWriteResources.elems[i].IsTexture)
{
// image load/store
GLint loc = gl.glGetUniformLocation(curProg, refl->ReadWriteResources.elems[i].name.elems);
if(loc >= 0)
{
gl.glGetUniformiv(curProg, loc, dummyReadback);
mapping.ReadWriteResources[i].bindset = 0;
mapping.ReadWriteResources[i].bind = dummyReadback[0];
mapping.ReadWriteResources[i].arraySize = 1;
}
// handle sampler arrays, use the base name
string name = refl->ReadWriteResources.elems[i].name.elems;
if(name.back() == ']')
{
do
{
name.pop_back();
} while(name.back() != '[');
name.pop_back();
}
GLuint idx = 0;
idx = gl.glGetProgramResourceIndex(curProg, eGL_UNIFORM, name.c_str());
if(idx == GL_INVALID_INDEX)
{
mapping.ReadWriteResources[i].used = false;
}
else
{
GLint used = 0;
gl.glGetProgramResourceiv(curProg, eGL_UNIFORM, idx, 1, &refEnum[shadIdx], 1, NULL, &used);
mapping.ReadWriteResources[i].used = (used != 0);
}
}
else if(!refl->ReadWriteResources.elems[i].IsTexture)
{
if(refl->ReadWriteResources.elems[i].variableType.descriptor.cols == 1 &&
refl->ReadWriteResources.elems[i].variableType.descriptor.rows == 1 &&
refl->ReadWriteResources.elems[i].variableType.descriptor.type == eVar_UInt)
{
// atomic uint
GLuint idx = gl.glGetProgramResourceIndex(curProg, eGL_UNIFORM, refl->Resources.elems[i].name.elems);
GLuint idx = gl.glGetProgramResourceIndex(curProg, eGL_UNIFORM, refl->ReadWriteResources.elems[i].name.elems);
if(idx == GL_INVALID_INDEX)
{
mapping.Resources[i].bindset = -1;
mapping.Resources[i].bind = -1;
mapping.Resources[i].used = false;
mapping.Resources[i].arraySize = 1;
mapping.ReadWriteResources[i].bindset = -1;
mapping.ReadWriteResources[i].bind = -1;
mapping.ReadWriteResources[i].used = false;
mapping.ReadWriteResources[i].arraySize = 1;
}
else
{
@@ -1862,10 +1915,10 @@ void GetBindpointMapping(const GLHookSet &gl, GLuint curProg, int shadIdx, Shade
if(atomicIndex == GL_INVALID_INDEX)
{
mapping.Resources[i].bindset = -1;
mapping.Resources[i].bind = -1;
mapping.Resources[i].used = false;
mapping.Resources[i].arraySize = 1;
mapping.ReadWriteResources[i].bindset = -1;
mapping.ReadWriteResources[i].bind = -1;
mapping.ReadWriteResources[i].used = false;
mapping.ReadWriteResources[i].arraySize = 1;
}
else
{
@@ -1877,45 +1930,45 @@ void GetBindpointMapping(const GLHookSet &gl, GLuint curProg, int shadIdx, Shade
eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER,
eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER,
};
mapping.Resources[i].bindset = 0;
gl.glGetActiveAtomicCounterBufferiv(curProg, atomicIndex, eGL_ATOMIC_COUNTER_BUFFER_BINDING, &mapping.Resources[i].bind);
mapping.ReadWriteResources[i].bindset = 0;
gl.glGetActiveAtomicCounterBufferiv(curProg, atomicIndex, eGL_ATOMIC_COUNTER_BUFFER_BINDING, &mapping.ReadWriteResources[i].bind);
GLint used = 0;
gl.glGetActiveAtomicCounterBufferiv(curProg, atomicIndex, atomicRefEnum[shadIdx], &used);
mapping.Resources[i].used = (used != 0);
mapping.Resources[i].arraySize = 1;
mapping.ReadWriteResources[i].used = (used != 0);
mapping.ReadWriteResources[i].arraySize = 1;
}
}
}
else
{
// shader storage buffer object
GLuint idx = gl.glGetProgramResourceIndex(curProg, eGL_SHADER_STORAGE_BLOCK, refl->Resources.elems[i].name.elems);
GLuint idx = gl.glGetProgramResourceIndex(curProg, eGL_SHADER_STORAGE_BLOCK, refl->ReadWriteResources.elems[i].name.elems);
if(idx == GL_INVALID_INDEX)
{
mapping.Resources[i].bindset = -1;
mapping.Resources[i].bind = -1;
mapping.Resources[i].used = false;
mapping.Resources[i].arraySize = 1;
mapping.ReadWriteResources[i].bindset = -1;
mapping.ReadWriteResources[i].bind = -1;
mapping.ReadWriteResources[i].used = false;
mapping.ReadWriteResources[i].arraySize = 1;
}
else
{
GLenum prop = eGL_BUFFER_BINDING;
mapping.Resources[i].bindset = 0;
gl.glGetProgramResourceiv(curProg, eGL_SHADER_STORAGE_BLOCK, idx, 1, &prop, 1, NULL, &mapping.Resources[i].bind);
mapping.ReadWriteResources[i].bindset = 0;
gl.glGetProgramResourceiv(curProg, eGL_SHADER_STORAGE_BLOCK, idx, 1, &prop, 1, NULL, &mapping.ReadWriteResources[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);
mapping.Resources[i].arraySize = 1;
mapping.ReadWriteResources[i].used = (used != 0);
mapping.ReadWriteResources[i].arraySize = 1;
}
}
}
else
{
mapping.Resources[i].bindset = -1;
mapping.Resources[i].bind = -1;
mapping.Resources[i].used = false;
mapping.Resources[i].arraySize = 1;
mapping.ReadWriteResources[i].bindset = -1;
mapping.ReadWriteResources[i].bind = -1;
mapping.ReadWriteResources[i].used = false;
mapping.ReadWriteResources[i].arraySize = 1;
}
}
@@ -2329,7 +2329,6 @@ void SPVModule::MakeReflection(ShaderReflection *reflection, ShaderBindpointMapp
res.IsSampler = true;
res.IsTexture = true;
res.IsSRV = true;
res.IsReadWrite = false;
SPVTypeData *sampledType = type->baseType;
if(sampledType->type == SPVTypeData::eImage)
@@ -2397,8 +2396,8 @@ void SPVModule::MakeReflection(ShaderReflection *reflection, ShaderBindpointMapp
create_array_uninit(mapping->ConstantBlocks, cblocks.size());
create_array_uninit(reflection->ConstantBlocks, cblocks.size());
create_array_uninit(mapping->Resources, resources.size());
create_array_uninit(reflection->Resources, resources.size());
create_array_uninit(mapping->ReadOnlyResources, resources.size());
create_array_uninit(reflection->ReadOnlyResources, resources.size());
for(size_t i=0; i < cblocks.size(); i++)
{
@@ -2409,9 +2408,9 @@ void SPVModule::MakeReflection(ShaderReflection *reflection, ShaderBindpointMapp
for(size_t i=0; i < resources.size(); i++)
{
mapping->Resources[i] = resources[i].map;
reflection->Resources[i] = resources[i].bindres;
reflection->Resources[i].bindPoint = (int32_t)i;
mapping->ReadOnlyResources[i] = resources[i].map;
reflection->ReadOnlyResources[i] = resources[i].bindres;
reflection->ReadOnlyResources[i].bindPoint = (int32_t)i;
}
}
+8 -4
View File
@@ -344,7 +344,6 @@ namespace renderdoc
public bool IsSampler;
public bool IsTexture;
public bool IsSRV;
public bool IsReadWrite;
public ShaderResourceType resType;
@@ -430,10 +429,13 @@ namespace renderdoc
public SigParameter[] OutputSig;
[CustomMarshalAs(CustomUnmanagedType.TemplatedArray)]
public ConstantBlock[] ConstantBlocks; // sparse - index indicates bind point
public ConstantBlock[] ConstantBlocks;
[CustomMarshalAs(CustomUnmanagedType.TemplatedArray)]
public ShaderResource[] Resources; // non-sparse, since bind points can overlap.
public ShaderResource[] ReadOnlyResources;
[CustomMarshalAs(CustomUnmanagedType.TemplatedArray)]
public ShaderResource[] ReadWriteResources;
[StructLayout(LayoutKind.Sequential)]
public struct Interface
@@ -463,6 +465,8 @@ namespace renderdoc
[CustomMarshalAs(CustomUnmanagedType.TemplatedArray)]
public BindpointMap[] ConstantBlocks;
[CustomMarshalAs(CustomUnmanagedType.TemplatedArray)]
public BindpointMap[] Resources;
public BindpointMap[] ReadOnlyResources;
[CustomMarshalAs(CustomUnmanagedType.TemplatedArray)]
public BindpointMap[] ReadWriteResources;
};
};
@@ -248,7 +248,7 @@ namespace renderdocui.Windows.PipelineState
if (shaderDetails != null)
{
foreach (var bind in shaderDetails.Resources)
foreach (var bind in shaderDetails.ReadOnlyResources)
{
if (bind.IsSRV && bind.bindPoint == i)
{
@@ -372,7 +372,7 @@ namespace renderdocui.Windows.PipelineState
if (shaderDetails != null)
{
foreach (var bind in shaderDetails.Resources)
foreach (var bind in shaderDetails.ReadOnlyResources)
{
if (bind.IsSampler && bind.bindPoint == i)
{
@@ -926,9 +926,9 @@ namespace renderdocui.Windows.PipelineState
if (state.m_CS.ShaderDetails != null)
{
foreach (var bind in state.m_CS.ShaderDetails.Resources)
foreach (var bind in state.m_CS.ShaderDetails.ReadWriteResources)
{
if (bind.IsReadWrite && bind.bindPoint == i)
if (bind.bindPoint == i)
{
shaderInput = bind;
break;
@@ -1254,9 +1254,9 @@ namespace renderdocui.Windows.PipelineState
if (state.m_PS.ShaderDetails != null)
{
foreach (var bind in state.m_PS.ShaderDetails.Resources)
foreach (var bind in state.m_PS.ShaderDetails.ReadWriteResources)
{
if (bind.IsReadWrite && bind.bindPoint == i + state.m_OM.UAVStartSlot)
if (bind.bindPoint == i + state.m_OM.UAVStartSlot)
{
shaderInput = bind;
break;
@@ -1612,72 +1612,70 @@ namespace renderdocui.Windows.PipelineState
if (deets != null)
{
foreach (var r in deets.Resources)
ShaderResource[] resources = uav ? deets.ReadWriteResources : deets.ReadOnlyResources;
foreach (var r in resources)
{
if(r.IsTexture)
if (r.IsTexture)
continue;
if ((r.IsSRV && !uav) || (r.IsReadWrite && uav))
if (r.bindPoint == bind)
{
if (r.bindPoint == bind)
if (r.variableType.members.Length == 0)
{
if (r.variableType.members.Length == 0)
if (view != null)
{
if (view != null)
if (view.Format.special && view.Format.specialFormat == SpecialFormat.R10G10B10A2)
{
if (view.Format.special && view.Format.specialFormat == SpecialFormat.R10G10B10A2)
{
if (view.Format.compType == FormatComponentType.UInt) format = "uintten";
if (view.Format.compType == FormatComponentType.UNorm) format = "unormten";
}
else if (!view.Format.special)
{
switch (view.Format.compByteWidth)
{
case 1:
{
if (view.Format.compType == FormatComponentType.UNorm) format = "unormb";
if (view.Format.compType == FormatComponentType.SNorm) format = "snormb";
if (view.Format.compType == FormatComponentType.UInt) format = "ubyte";
if (view.Format.compType == FormatComponentType.SInt) format = "byte";
break;
}
case 2:
{
if (view.Format.compType == FormatComponentType.UNorm) format = "unormh";
if (view.Format.compType == FormatComponentType.SNorm) format = "snormh";
if (view.Format.compType == FormatComponentType.UInt) format = "ushort";
if (view.Format.compType == FormatComponentType.SInt) format = "short";
if (view.Format.compType == FormatComponentType.Float) format = "half";
break;
}
case 4:
{
if (view.Format.compType == FormatComponentType.UNorm) format = "unormf";
if (view.Format.compType == FormatComponentType.SNorm) format = "snormf";
if (view.Format.compType == FormatComponentType.UInt) format = "uint";
if (view.Format.compType == FormatComponentType.SInt) format = "int";
if (view.Format.compType == FormatComponentType.Float) format = "float";
break;
}
}
format += view.Format.compCount;
}
if (view.Format.compType == FormatComponentType.UInt) format = "uintten";
if (view.Format.compType == FormatComponentType.UNorm) format = "unormten";
}
else if (!view.Format.special)
{
switch (view.Format.compByteWidth)
{
case 1:
{
if (view.Format.compType == FormatComponentType.UNorm) format = "unormb";
if (view.Format.compType == FormatComponentType.SNorm) format = "snormb";
if (view.Format.compType == FormatComponentType.UInt) format = "ubyte";
if (view.Format.compType == FormatComponentType.SInt) format = "byte";
break;
}
case 2:
{
if (view.Format.compType == FormatComponentType.UNorm) format = "unormh";
if (view.Format.compType == FormatComponentType.SNorm) format = "snormh";
if (view.Format.compType == FormatComponentType.UInt) format = "ushort";
if (view.Format.compType == FormatComponentType.SInt) format = "short";
if (view.Format.compType == FormatComponentType.Float) format = "half";
break;
}
case 4:
{
if (view.Format.compType == FormatComponentType.UNorm) format = "unormf";
if (view.Format.compType == FormatComponentType.SNorm) format = "snormf";
if (view.Format.compType == FormatComponentType.UInt) format = "uint";
if (view.Format.compType == FormatComponentType.SInt) format = "int";
if (view.Format.compType == FormatComponentType.Float) format = "float";
break;
}
}
if (format == "" && r.variableType.Name.Length > 0)
format = r.variableType.Name;
format += view.Format.compCount;
}
}
format += " " + r.name + ";";
}
else
{
format = "// struct " + r.variableType.Name + Environment.NewLine +
"{" + Environment.NewLine + FormatMembers(1, "", r.variableType.members) + "}";
}
break;
if (format == "" && r.variableType.Name.Length > 0)
format = r.variableType.Name;
format += " " + r.name + ";";
}
else
{
format = "// struct " + r.variableType.Name + Environment.NewLine +
"{" + Environment.NewLine + FormatMembers(1, "", r.variableType.members) + "}";
}
break;
}
}
}
@@ -1936,33 +1934,37 @@ namespace renderdocui.Windows.PipelineState
var shType = String.Format("{0}S", stage.stage.ToString()[0]);
foreach (var res in shaderDetails.Resources)
for (int i = 0; i < 2; i++)
{
if (res.IsSampler)
ShaderResource[] resources = (i == 0 ? shaderDetails.ReadOnlyResources : shaderDetails.ReadWriteResources);
foreach (var res in resources)
{
hlsl += String.Format("//SamplerComparisonState {0} : register(s{1}); // can't disambiguate", res.name, res.bindPoint) + nl;
hlsl += String.Format("SamplerState {0} : register(s{1}); // can't disambiguate", res.name, res.bindPoint) + nl;
}
else
{
char regChar = 't';
if (res.IsReadWrite)
if (res.IsSampler)
{
hlsl += "RW";
regChar = 'u';
}
if (res.IsTexture)
{
hlsl += String.Format("{0}<{1}> {2} : register({3}{4});", res.resType.ToString(), res.variableType.descriptor.name, res.name, regChar, res.bindPoint) + nl;
hlsl += String.Format("//SamplerComparisonState {0} : register(s{1}); // can't disambiguate", res.name, res.bindPoint) + nl;
hlsl += String.Format("SamplerState {0} : register(s{1}); // can't disambiguate", res.name, res.bindPoint) + nl;
}
else
{
if (res.variableType.descriptor.rows == 1)
hlsl += String.Format("Buffer<{0}> {1} : register({2}{3});", res.variableType.descriptor.name, res.name, regChar, res.bindPoint) + nl;
char regChar = 't';
if (i == 1)
{
hlsl += "RW";
regChar = 'u';
}
if (res.IsTexture)
{
hlsl += String.Format("{0}<{1}> {2} : register({3}{4});", res.resType.ToString(), res.variableType.descriptor.name, res.name, regChar, res.bindPoint) + nl;
}
else
hlsl += String.Format("StructuredBuffer<{0}> {1} : register({2}{3});", res.variableType.descriptor.name, res.name, regChar, res.bindPoint) + nl;
{
if (res.variableType.descriptor.rows == 1)
hlsl += String.Format("Buffer<{0}> {1} : register({2}{3});", res.variableType.descriptor.name, res.name, regChar, res.bindPoint) + nl;
else
hlsl += String.Format("StructuredBuffer<{0}> {1} : register({2}{3});", res.variableType.descriptor.name, res.name, regChar, res.bindPoint) + nl;
}
}
}
}
@@ -2518,9 +2520,9 @@ namespace renderdocui.Windows.PipelineState
if (refl != null)
{
foreach (var bind in refl.Resources)
foreach (var bind in refl.ReadWriteResources)
{
if (bind.IsReadWrite && bind.bindPoint == i)
if (bind.bindPoint == i)
{
shaderInput = bind;
break;
@@ -270,12 +270,12 @@ namespace renderdocui.Windows.PipelineState
if (shaderDetails != null)
{
foreach (var bind in shaderDetails.Resources)
foreach (var bind in shaderDetails.ReadOnlyResources)
{
if (bind.IsSRV && !bind.IsReadWrite && mapping.Resources[bind.bindPoint].bind == i)
if (bind.IsSRV && mapping.ReadOnlyResources[bind.bindPoint].bind == i)
{
shaderInput = bind;
map = mapping.Resources[bind.bindPoint];
map = mapping.ReadOnlyResources[bind.bindPoint];
}
}
}
@@ -557,20 +557,14 @@ namespace renderdocui.Windows.PipelineState
if (shaderDetails != null)
{
UInt32 i = 0;
foreach (var res in shaderDetails.Resources)
foreach (var res in shaderDetails.ReadWriteResources)
{
int bindPoint = stage.BindpointMapping.Resources[i].bind;
int bindPoint = stage.BindpointMapping.ReadWriteResources[i].bind;
bool atomic = false;
bool ssbo = false;
bool image = false;
if (!res.IsReadWrite)
{
i++;
continue;
}
GLPipelineState.Buffer bf = null;
GLPipelineState.ImageLoadStore im = null;
ResourceId id = ResourceId.Null;
@@ -609,7 +603,7 @@ namespace renderdocui.Windows.PipelineState
}
bool filledSlot = id != ResourceId.Null;
bool usedSlot = stage.BindpointMapping.Resources[i].used;
bool usedSlot = stage.BindpointMapping.ReadWriteResources[i].used;
// show if
if (usedSlot || // it's referenced by the shader - regardless of empty or not
@@ -1658,7 +1652,7 @@ namespace renderdocui.Windows.PipelineState
var deets = stage.ShaderDetails;
ShaderResource r = deets.Resources[rwtag.idx];
ShaderResource r = deets.ReadWriteResources[rwtag.idx];
if (deets != null)
{
@@ -335,9 +335,9 @@ namespace renderdocui.Windows.PipelineState
// string formatted with all the relevant data
if (stage.ShaderDetails != null)
{
foreach (var shaderRes in stage.ShaderDetails.Resources)
foreach (var shaderRes in stage.ShaderDetails.ReadOnlyResources)
{
BindpointMap bindMap = stage.BindpointMapping.Resources[shaderRes.bindPoint];
BindpointMap bindMap = stage.BindpointMapping.ReadOnlyResources[shaderRes.bindPoint];
VulkanPipelineState.Pipeline.DescriptorSet.DescriptorBinding.BindingElement[] slotBinds = null;
ShaderBindType bindType = ShaderBindType.Unknown;
@@ -1562,223 +1562,6 @@ namespace renderdocui.Windows.PipelineState
// HLSL source available for this shader.
private void shaderedit_Click(object sender, EventArgs e)
{
VulkanPipelineState.ShaderStage stage = GetStageForSender(sender);
if (stage == null) return;
ShaderReflection shaderDetails = stage.ShaderDetails;
if (stage.Shader == ResourceId.Null || shaderDetails == null) return;
var entryFunc = String.Format("EditedShader{0}S", stage.stage.ToString()[0]);
string mainfile = "";
var files = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
if (shaderDetails.DebugInfo.entryFunc.Length > 0 && shaderDetails.DebugInfo.files.Length > 0)
{
entryFunc = shaderDetails.DebugInfo.entryFunc;
foreach (var s in shaderDetails.DebugInfo.files)
files.Add(s.BaseFilename, s.filetext);
int entryFile = shaderDetails.DebugInfo.entryFile;
if (entryFile < 0 || entryFile >= shaderDetails.DebugInfo.files.Length)
entryFile = 0;
mainfile = shaderDetails.DebugInfo.files[entryFile].BaseFilename;
}
else
{
var nl = Environment.NewLine;
var nl2 = Environment.NewLine + Environment.NewLine;
string hlsl = "// No HLSL available - function stub generated" + nl2;
var shType = String.Format("{0}S", stage.stage.ToString()[0]);
foreach (var res in shaderDetails.Resources)
{
if (res.IsSampler)
{
hlsl += String.Format("//SamplerComparisonState {0} : register(s{1}); // can't disambiguate", res.name, res.bindPoint) + nl;
hlsl += String.Format("SamplerState {0} : register(s{1}); // can't disambiguate", res.name, res.bindPoint) + nl;
}
else
{
char regChar = 't';
if (res.IsReadWrite)
{
hlsl += "RW";
regChar = 'u';
}
if (res.IsTexture)
{
hlsl += String.Format("{0}<{1}> {2} : register({3}{4});", res.resType.ToString(), res.variableType.descriptor.name, res.name, regChar, res.bindPoint) + nl;
}
else
{
if (res.variableType.descriptor.rows == 1)
hlsl += String.Format("Buffer<{0}> {1} : register({2}{3});", res.variableType.descriptor.name, res.name, regChar, res.bindPoint) + nl;
else
hlsl += String.Format("StructuredBuffer<{0}> {1} : register({2}{3});", res.variableType.descriptor.name, res.name, regChar, res.bindPoint) + nl;
}
}
}
hlsl += nl2;
string cbuffers = "";
int cbufIdx = 0;
foreach (var cbuf in shaderDetails.ConstantBlocks)
{
if (cbuf.name.Length > 0 && cbuf.variables.Length > 0)
{
cbuffers += String.Format("cbuffer {0} : register(b{1}) {{", cbuf.name, cbufIdx) + nl;
MakeShaderVariablesHLSL(true, cbuf.variables, ref cbuffers, ref hlsl);
cbuffers += "};" + nl2;
}
cbufIdx++;
}
hlsl += cbuffers + nl2;
hlsl += String.Format("struct {0}Input{1}{{{1}", shType, nl);
foreach(var sig in shaderDetails.InputSig)
hlsl += String.Format("\t{0} {1} : {2};" + nl, sig.TypeString, sig.varName.Length > 0 ? sig.varName : ("param" + sig.regIndex), sig.D3D11SemanticString);
hlsl += "};" + nl2;
hlsl += String.Format("struct {0}Output{1}{{{1}", shType, nl);
foreach (var sig in shaderDetails.OutputSig)
hlsl += String.Format("\t{0} {1} : {2};" + nl, sig.TypeString, sig.varName.Length > 0 ? sig.varName : ("param" + sig.regIndex), sig.D3D11SemanticString);
hlsl += "};" + nl2;
hlsl += String.Format("{0}Output {1}(in {0}Input IN){2}{{{2}\t{0}Output OUT = ({0}Output)0;{2}{2}\t// ...{2}{2}\treturn OUT;{2}}}{2}", shType, entryFunc, nl);
mainfile = "generated.hlsl";
files.Add(mainfile, hlsl);
}
if (files.Count == 0)
return;
ShaderViewer sv = new ShaderViewer(m_Core, false, entryFunc, files,
// Save Callback
(ShaderViewer viewer, Dictionary<string, string> updatedfiles) =>
{
string compileSource = updatedfiles[mainfile];
// try and match up #includes against the files that we have. This isn't always
// possible as fxc only seems to include the source for files if something in
// that file was included in the compiled output. So you might end up with
// dangling #includes - we just have to ignore them
int offs = compileSource.IndexOf("#include");
while(offs >= 0)
{
// search back to ensure this is a valid #include (ie. not in a comment).
// Must only see whitespace before, then a newline.
int ws = Math.Max(0, offs-1);
while (ws >= 0 && (compileSource[ws] == ' ' || compileSource[ws] == '\t'))
ws--;
// not valid? jump to next.
if (ws > 0 && compileSource[ws] != '\n')
{
offs = compileSource.IndexOf("#include", offs + 1);
continue;
}
int start = ws+1;
bool tail = true;
int lineEnd = compileSource.IndexOf("\n", start+1);
if(lineEnd == -1)
{
lineEnd = compileSource.Length;
tail = false;
}
ws = offs + "#include".Length;
while (compileSource[ws] == ' ' || compileSource[ws] == '\t')
ws++;
string line = compileSource.Substring(offs, lineEnd-offs+1);
if (compileSource[ws] != '<' && compileSource[ws] != '"')
{
viewer.ShowErrors("Invalid #include directive found:\r\n" + line);
return;
}
// find matching char, either <> or "";
int end = compileSource.IndexOf(compileSource[ws] == '"' ? '"' : '>', ws + 1);
if (end == -1)
{
viewer.ShowErrors("Invalid #include directive found:\r\n" + line);
return;
}
string fname = compileSource.Substring(ws + 1, end - ws - 1);
string fileText = "";
if (updatedfiles.ContainsKey(fname))
fileText = updatedfiles[fname];
else
fileText = "// Can't find file " + fname + "\n";
compileSource = compileSource.Substring(0, offs) + "\n\n" + fileText + "\n\n" + (tail ? compileSource.Substring(lineEnd + 1) : "");
// need to start searching from the beginning - wasteful but allows nested includes to work
offs = compileSource.IndexOf("#include");
}
if (updatedfiles.ContainsKey("@cmdline"))
compileSource = updatedfiles["@cmdline"] + "\n\n" + compileSource;
// invoke off to the ReplayRenderer to replace the log's shader
// with our edited one
m_Core.Renderer.BeginInvoke((ReplayRenderer r) =>
{
string errs = "";
uint flags = shaderDetails.DebugInfo.compileFlags;
ResourceId from = stage.Shader;
ResourceId to = r.BuildTargetShader(entryFunc, compileSource, flags, stage.stage, out errs);
viewer.BeginInvoke((MethodInvoker)delegate { viewer.ShowErrors(errs); });
if (to == ResourceId.Null)
{
r.RemoveReplacement(from);
}
else
{
r.ReplaceResource(from, to);
}
});
},
// Close Callback
() =>
{
// remove the replacement on close (we could make this more sophisticated if there
// was a place to control replaced resources/shaders).
m_Core.Renderer.BeginInvoke((ReplayRenderer r) =>
{
r.RemoveReplacement(stage.Shader);
});
});
sv.Show(m_DockContent.DockPanel);
}
private void ShowCBuffer(VulkanPipelineState.ShaderStage stage, CBufferTag tag)
+86 -79
View File
@@ -466,7 +466,7 @@ namespace renderdocui.Windows
disasm = FriendlyName(disasm, stem, "", cbuf.variables);
}
foreach (var r in m_ShaderDetails.Resources)
foreach (var r in m_ShaderDetails.ReadOnlyResources)
{
if (r.IsSRV)
{
@@ -484,14 +484,14 @@ namespace renderdocui.Windows
Regex rgx = new Regex(needle);
disasm = rgx.Replace(disasm, replacement);
}
if (r.IsReadWrite)
{
var needle = string.Format(", u{0}([^0-9])", r.bindPoint);
var replacement = string.Format(", {0}$1", r.name);
}
foreach (var r in m_ShaderDetails.ReadWriteResources)
{
var needle = string.Format(", u{0}([^0-9])", r.bindPoint);
var replacement = string.Format(", {0}$1", r.name);
Regex rgx = new Regex(needle);
disasm = rgx.Replace(disasm, replacement);
}
Regex rgx = new Regex(needle);
disasm = rgx.Replace(disasm, replacement);
}
}
@@ -1304,6 +1304,70 @@ namespace renderdocui.Windows
return var.Row(0, VarType.Float).ToString();
}
private void AddResourceRegister(ShaderResource slot, D3D11PipelineState.ShaderStage.ResourceView res)
{
bool found = false;
var name = slot.bindPoint + " (" + slot.name + ")";
foreach (var tex in m_Core.CurTextures)
{
if (tex.ID == res.Resource)
{
var node = new TreelistView.Node(new object[] {
"t" + name, "Texture",
tex.width + "x" + tex.height + "x" + (tex.depth > 1 ? tex.depth : tex.arraysize) +
"[" + tex.mips + "] @ " + tex.format + " - " + tex.name
});
node.Tag = null;
constantRegs.Nodes.Add(node);
found = true;
break;
}
}
if (!found)
{
foreach (var buf in m_Core.CurBuffers)
{
if (buf.ID == res.Resource)
{
string prefix = "u";
if (slot.IsSRV)
prefix = "t";
var node = new TreelistView.Node(new object[] {
prefix + name, "Buffer",
buf.length + " - " + buf.name
});
node.Tag = null;
constantRegs.Nodes.Add(node);
found = true;
break;
}
}
}
if (!found)
{
string prefix = "u";
if (slot.IsSRV)
prefix = "t";
var node = new TreelistView.Node(new object[] {
prefix + name, "Resource",
"unknown"
});
node.Tag = null;
constantRegs.Nodes.Add(node);
}
}
public void UpdateDebugging()
{
if (m_Trace == null || m_Trace.states == null || m_Trace.states.Length == 0)
@@ -1381,81 +1445,24 @@ namespace renderdocui.Windows
var pipestate = m_Core.CurD3D11PipelineState;
foreach (var slot in m_ShaderDetails.Resources)
foreach (ShaderResource slot in m_ShaderDetails.ReadWriteResources)
{
D3D11PipelineState.ShaderStage.ResourceView res = null;
if (m_Stage.stage == ShaderStageType.Pixel)
res = pipestate.m_OM.UAVs[slot.bindPoint - pipestate.m_OM.UAVStartSlot];
else
res = m_Stage.UAVs[slot.bindPoint];
AddResourceRegister(slot, res);
}
foreach (ShaderResource slot in m_ShaderDetails.ReadOnlyResources)
{
if (slot.IsSampler)
continue;
var res = m_Stage.SRVs[slot.bindPoint];
if (slot.IsReadWrite)
{
if(m_Stage.stage == ShaderStageType.Pixel)
res = pipestate.m_OM.UAVs[slot.bindPoint - pipestate.m_OM.UAVStartSlot];
else
res = m_Stage.UAVs[slot.bindPoint];
}
bool found = false;
var name = slot.bindPoint + " (" + slot.name + ")";
foreach (var tex in m_Core.CurTextures)
{
if (tex.ID == res.Resource)
{
var node = new TreelistView.Node(new object[] {
"t" + name, "Texture",
tex.width + "x" + tex.height + "x" + (tex.depth > 1 ? tex.depth : tex.arraysize) +
"[" + tex.mips + "] @ " + tex.format + " - " + tex.name
});
node.Tag = null;
constantRegs.Nodes.Add(node);
found = true;
break;
}
}
if (!found)
{
foreach (var buf in m_Core.CurBuffers)
{
if (buf.ID == res.Resource)
{
string prefix = "u";
if (slot.IsSRV)
prefix = "t";
var node = new TreelistView.Node(new object[] {
prefix + name, "Buffer",
buf.length + " - " + buf.name
});
node.Tag = null;
constantRegs.Nodes.Add(node);
found = true;
break;
}
}
}
if (!found)
{
string prefix = "u";
if (slot.IsSRV)
prefix = "t";
var node = new TreelistView.Node(new object[] {
prefix + name, "Resource",
"unknown"
});
node.Tag = null;
constantRegs.Nodes.Add(node);
}
AddResourceRegister(slot, m_Stage.SRVs[slot.bindPoint]);
}
constantRegs.EndUpdate();
+4 -4
View File
@@ -1218,9 +1218,9 @@ namespace renderdocui.Windows
if (details != null)
{
foreach (var bind in details.Resources)
foreach (var bind in details.ReadWriteResources)
{
if (mapping.Resources[bind.bindPoint].bind == rw && bind.IsReadWrite)
if (mapping.ReadWriteResources[bind.bindPoint].bind == rw)
{
used = true;
bindName = "<" + bind.name + ">";
@@ -1376,9 +1376,9 @@ namespace renderdocui.Windows
if (details != null)
{
foreach (var bind in details.Resources)
foreach (var bind in details.ReadOnlyResources)
{
if (mapping.Resources[bind.bindPoint].bind == i && bind.IsSRV)
if (mapping.ReadOnlyResources[bind.bindPoint].bind == i && bind.IsSRV)
{
used = true;
bindName = "<" + bind.name + ">";