mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-29 13:20:54 +00:00
Generate baked per-pipeline static descriptor access on Vulkan
This commit is contained in:
@@ -1242,7 +1242,8 @@ struct ShaderResource
|
||||
bool operator==(const ShaderResource &o) const
|
||||
{
|
||||
return resType == o.resType && name == o.name && variableType == o.variableType &&
|
||||
bindPoint == o.bindPoint && isTexture == o.isTexture && isReadOnly == o.isReadOnly;
|
||||
bindPoint == o.bindPoint && isTexture == o.isTexture && hasSampler == o.hasSampler &&
|
||||
isReadOnly == o.isReadOnly;
|
||||
}
|
||||
bool operator<(const ShaderResource &o) const
|
||||
{
|
||||
@@ -1256,6 +1257,8 @@ struct ShaderResource
|
||||
return bindPoint < o.bindPoint;
|
||||
if(!(isTexture == o.isTexture))
|
||||
return isTexture < o.isTexture;
|
||||
if(!(hasSampler == o.hasSampler))
|
||||
return hasSampler < o.hasSampler;
|
||||
if(!(isReadOnly == o.isReadOnly))
|
||||
return isReadOnly < o.isReadOnly;
|
||||
return false;
|
||||
@@ -1280,6 +1283,8 @@ struct ShaderResource
|
||||
|
||||
DOCUMENT("``True`` if this resource is a texture, otherwise it is a buffer.");
|
||||
bool isTexture;
|
||||
DOCUMENT("``True`` if this texture resource has a sampler as well.");
|
||||
bool hasSampler = false;
|
||||
DOCUMENT(R"(``True`` if this resource is available to the shader for reading only, otherwise it is
|
||||
able to be read from and written to arbitrarily.
|
||||
)");
|
||||
|
||||
@@ -1757,6 +1757,8 @@ void MakeShaderReflection(GLenum shadType, GLuint sepProg, ShaderReflection &ref
|
||||
continue;
|
||||
}
|
||||
|
||||
res.hasSampler = res.isReadOnly;
|
||||
|
||||
char *namebuf = new char[values[1] + 1];
|
||||
GL.glGetProgramResourceName(sepProg, eGL_UNIFORM, u, values[1], NULL, namebuf);
|
||||
namebuf[values[1]] = 0;
|
||||
|
||||
@@ -1437,7 +1437,10 @@ void Reflector::MakeReflection(const GraphicsAPI sourceAPI, const ShaderStage st
|
||||
Id imageTypeId = varType->id;
|
||||
|
||||
if(varType->type == DataType::SampledImageType)
|
||||
{
|
||||
imageTypeId = sampledImageTypes[varType->id].baseId;
|
||||
res.hasSampler = true;
|
||||
}
|
||||
|
||||
const Image &imageType = imageTypes[imageTypeId];
|
||||
|
||||
|
||||
@@ -566,6 +566,8 @@ VkShaderStageFlags ShaderMaskFromIndex(size_t index)
|
||||
VK_SHADER_STAGE_MESH_BIT_EXT,
|
||||
};
|
||||
|
||||
RDCCOMPILE_ASSERT(ARRAY_COUNT(mask) == NumShaderStages, "Array is out of date");
|
||||
|
||||
if(index < ARRAY_COUNT(mask))
|
||||
return mask[index];
|
||||
|
||||
|
||||
@@ -817,6 +817,111 @@ bool CreateDescriptorWritesForSlotData(WrappedVulkan *vk, rdcarray<VkWriteDescri
|
||||
return ret;
|
||||
}
|
||||
|
||||
void VulkanCreationInfo::Pipeline::Shader::ProcessStaticDescriptorAccess(
|
||||
rdcarray<DescriptorAccess> &staticDescriptorAccess,
|
||||
rdcarray<const DescSetLayout *> setLayoutInfos) const
|
||||
{
|
||||
if(!refl)
|
||||
return;
|
||||
|
||||
DescriptorAccess access;
|
||||
access.stage = refl->stage;
|
||||
|
||||
// we will store the descriptor set in byteSize to be decoded into descriptorStore later
|
||||
access.byteSize = 0;
|
||||
|
||||
staticDescriptorAccess.reserve(staticDescriptorAccess.size() + mapping->constantBlocks.size() +
|
||||
mapping->samplers.size() + mapping->readOnlyResources.size() +
|
||||
mapping->readWriteResources.size());
|
||||
|
||||
RDCASSERT(mapping->constantBlocks.size() < 0xffff, mapping->constantBlocks.size());
|
||||
for(uint16_t i = 0; i < mapping->constantBlocks.size(); i++)
|
||||
{
|
||||
const Bindpoint &bind = mapping->constantBlocks[i];
|
||||
// arrayed descriptors will be handled with bindless feedback
|
||||
if(bind.arraySize > 1)
|
||||
continue;
|
||||
|
||||
access.staticallyUnused = !bind.used;
|
||||
access.type = DescriptorType::ConstantBuffer;
|
||||
access.index = i;
|
||||
|
||||
if(bind.bindset == PushConstantBindSet)
|
||||
{
|
||||
access.byteSize = bind.bindset;
|
||||
access.byteOffset = 0;
|
||||
staticDescriptorAccess.push_back(access);
|
||||
}
|
||||
else if(bind.bindset == SpecializationConstantBindSet)
|
||||
{
|
||||
access.byteSize = bind.bindset;
|
||||
access.byteOffset = 0;
|
||||
staticDescriptorAccess.push_back(access);
|
||||
}
|
||||
else
|
||||
{
|
||||
access.byteSize = bind.bindset;
|
||||
access.byteOffset = setLayoutInfos[bind.bindset]->bindings[bind.bind].elemOffset;
|
||||
staticDescriptorAccess.push_back(access);
|
||||
}
|
||||
}
|
||||
|
||||
RDCASSERT(mapping->samplers.size() < 0xffff, mapping->samplers.size());
|
||||
for(uint16_t i = 0; i < mapping->samplers.size(); i++)
|
||||
{
|
||||
const Bindpoint &bind = mapping->samplers[i];
|
||||
// arrayed descriptors will be handled with bindless feedback
|
||||
if(bind.arraySize > 1)
|
||||
continue;
|
||||
|
||||
access.staticallyUnused = !bind.used;
|
||||
access.type = DescriptorType::Sampler;
|
||||
access.index = i;
|
||||
access.byteSize = bind.bindset;
|
||||
access.byteOffset = setLayoutInfos[bind.bindset]->bindings[bind.bind].elemOffset;
|
||||
staticDescriptorAccess.push_back(access);
|
||||
}
|
||||
|
||||
RDCASSERT(mapping->readOnlyResources.size() < 0xffff, mapping->readOnlyResources.size());
|
||||
for(uint16_t i = 0; i < mapping->readOnlyResources.size(); i++)
|
||||
{
|
||||
const Bindpoint &bind = mapping->readOnlyResources[i];
|
||||
// arrayed descriptors will be handled with bindless feedback
|
||||
if(bind.arraySize > 1)
|
||||
continue;
|
||||
|
||||
access.staticallyUnused = !bind.used;
|
||||
access.type = DescriptorType::Image;
|
||||
if(!refl->readOnlyResources[i].isTexture)
|
||||
access.type = DescriptorType::TypedBuffer;
|
||||
if(refl->readOnlyResources[i].hasSampler)
|
||||
access.type = DescriptorType::ImageSampler;
|
||||
access.index = i;
|
||||
access.byteSize = bind.bindset;
|
||||
access.byteOffset = setLayoutInfos[bind.bindset]->bindings[bind.bind].elemOffset;
|
||||
staticDescriptorAccess.push_back(access);
|
||||
}
|
||||
|
||||
RDCASSERT(mapping->readWriteResources.size() < 0xffff, mapping->readWriteResources.size());
|
||||
for(uint16_t i = 0; i < mapping->readWriteResources.size(); i++)
|
||||
{
|
||||
const Bindpoint &bind = mapping->readWriteResources[i];
|
||||
// arrayed descriptors will be handled with bindless feedback
|
||||
if(bind.arraySize > 1)
|
||||
continue;
|
||||
|
||||
access.staticallyUnused = !bind.used;
|
||||
access.type = DescriptorType::ReadWriteImage;
|
||||
if(!refl->readWriteResources[i].isTexture)
|
||||
access.type = DescriptorType::ReadWriteBuffer;
|
||||
|
||||
access.index = i;
|
||||
access.byteSize = bind.bindset;
|
||||
access.byteOffset = setLayoutInfos[bind.bindset]->bindings[bind.bind].elemOffset;
|
||||
staticDescriptorAccess.push_back(access);
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan,
|
||||
VulkanCreationInfo &info, ResourceId id,
|
||||
const VkGraphicsPipelineCreateInfo *pCreateInfo)
|
||||
@@ -1487,6 +1592,13 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rdcarray<const DescSetLayout *> setLayoutInfos;
|
||||
for(ResourceId setLayout : descSetLayouts)
|
||||
setLayoutInfos.push_back(&info.m_DescSetLayout[setLayout]);
|
||||
|
||||
for(const Shader &shad : shaders)
|
||||
shad.ProcessStaticDescriptorAccess(staticDescriptorAccess, setLayoutInfos);
|
||||
}
|
||||
|
||||
void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info,
|
||||
@@ -1585,6 +1697,13 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, Vulk
|
||||
alphaToCoverageEnable = false;
|
||||
logicOpEnable = false;
|
||||
logicOp = VK_LOGIC_OP_NO_OP;
|
||||
|
||||
rdcarray<const DescSetLayout *> setLayoutInfos;
|
||||
for(ResourceId setLayout : descSetLayouts)
|
||||
setLayoutInfos.push_back(&info.m_DescSetLayout[setLayout]);
|
||||
|
||||
for(const Shader &shad : shaders)
|
||||
shad.ProcessStaticDescriptorAccess(staticDescriptorAccess, setLayoutInfos);
|
||||
}
|
||||
|
||||
void VulkanCreationInfo::PipelineLayout::Init(VulkanResourceManager *resourceMan,
|
||||
|
||||
@@ -275,9 +275,14 @@ struct VulkanCreationInfo
|
||||
|
||||
// VkPipelineShaderStageRequiredSubgroupSizeCreateInfo
|
||||
uint32_t requiredSubgroupSize = 0;
|
||||
|
||||
void ProcessStaticDescriptorAccess(rdcarray<DescriptorAccess> &staticDescriptorAccess,
|
||||
rdcarray<const DescSetLayout *> setLayoutInfos) const;
|
||||
};
|
||||
Shader shaders[NumShaderStages];
|
||||
|
||||
rdcarray<DescriptorAccess> staticDescriptorAccess;
|
||||
|
||||
// VkPipelineVertexInputStateCreateInfo
|
||||
struct VertBinding
|
||||
{
|
||||
|
||||
@@ -2607,7 +2607,46 @@ rdcarray<SamplerDescriptor> VulkanReplay::GetSamplerDescriptors(ResourceId descr
|
||||
|
||||
rdcarray<DescriptorAccess> VulkanReplay::GetDescriptorAccess()
|
||||
{
|
||||
return {};
|
||||
VulkanResourceManager *rm = m_pDriver->GetResourceManager();
|
||||
|
||||
const VulkanRenderState &state = m_pDriver->m_RenderState;
|
||||
|
||||
rdcarray<DescriptorAccess> ret;
|
||||
|
||||
if(state.graphics.pipeline != ResourceId())
|
||||
ret.append(m_pDriver->m_CreationInfo.m_Pipeline[state.graphics.pipeline].staticDescriptorAccess);
|
||||
|
||||
if(state.compute.pipeline != ResourceId())
|
||||
ret.append(m_pDriver->m_CreationInfo.m_Pipeline[state.compute.pipeline].staticDescriptorAccess);
|
||||
|
||||
for(DescriptorAccess &access : ret)
|
||||
{
|
||||
uint32_t bindset = (uint32_t)access.byteSize;
|
||||
access.byteSize = 1;
|
||||
if(bindset == PushConstantBindSet || bindset == SpecializationConstantBindSet)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
else
|
||||
{
|
||||
const rdcarray<VulkanStatePipeline::DescriptorAndOffsets> &descSets =
|
||||
access.stage == ShaderStage::Compute ? state.compute.descSets : state.graphics.descSets;
|
||||
|
||||
if(bindset >= descSets.size())
|
||||
{
|
||||
RDCERR("Unbound descriptor set referenced in static usage");
|
||||
}
|
||||
else
|
||||
{
|
||||
access.descriptorStore = rm->GetOriginalID(descSets[bindset].descSet);
|
||||
}
|
||||
}
|
||||
|
||||
if(access.descriptorStore == ResourceId())
|
||||
access = DescriptorAccess();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void VulkanReplay::FillCBufferVariables(ResourceId pipeline, ResourceId shader, ShaderStage stage,
|
||||
|
||||
@@ -222,6 +222,7 @@ void DoSerialise(SerialiserType &ser, ShaderResource &el)
|
||||
SERIALISE_MEMBER(variableType);
|
||||
SERIALISE_MEMBER(bindPoint);
|
||||
SERIALISE_MEMBER(isTexture);
|
||||
SERIALISE_MEMBER(hasSampler);
|
||||
SERIALISE_MEMBER(isReadOnly);
|
||||
|
||||
SIZE_CHECK(112);
|
||||
|
||||
Reference in New Issue
Block a user