mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-08 16:50:44 +00:00
Add serialization of VK_EXT_shader_object types
This commit is contained in:
committed by
Baldur Karlsson
parent
71d3e41fbf
commit
0b0d8b4703
@@ -1418,6 +1418,8 @@ DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT);
|
||||
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceShaderImageFootprintFeaturesNV);
|
||||
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceShaderIntegerDotProductFeatures);
|
||||
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceShaderIntegerDotProductProperties);
|
||||
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceShaderObjectFeaturesEXT);
|
||||
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceShaderObjectPropertiesEXT);
|
||||
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures);
|
||||
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR);
|
||||
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceShaderTerminateInvocationFeatures);
|
||||
@@ -1526,6 +1528,7 @@ DECLARE_REFLECTION_STRUCT(VkSemaphoreSignalInfo);
|
||||
DECLARE_REFLECTION_STRUCT(VkSemaphoreSubmitInfo);
|
||||
DECLARE_REFLECTION_STRUCT(VkSemaphoreTypeCreateInfo);
|
||||
DECLARE_REFLECTION_STRUCT(VkSemaphoreWaitInfo);
|
||||
DECLARE_REFLECTION_STRUCT(VkShaderCreateInfoEXT);
|
||||
DECLARE_REFLECTION_STRUCT(VkShaderModuleCreateInfo);
|
||||
DECLARE_REFLECTION_STRUCT(VkShaderModuleValidationCacheCreateInfoEXT);
|
||||
DECLARE_REFLECTION_STRUCT(VkSharedPresentSurfaceCapabilitiesKHR);
|
||||
@@ -1849,6 +1852,8 @@ DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT);
|
||||
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceShaderImageFootprintFeaturesNV);
|
||||
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceShaderIntegerDotProductFeatures);
|
||||
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceShaderIntegerDotProductProperties);
|
||||
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceShaderObjectFeaturesEXT);
|
||||
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceShaderObjectPropertiesEXT);
|
||||
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures);
|
||||
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR);
|
||||
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceShaderTerminateInvocationFeatures);
|
||||
@@ -1954,6 +1959,7 @@ DECLARE_DESERIALISE_TYPE(VkSemaphoreSignalInfo);
|
||||
DECLARE_DESERIALISE_TYPE(VkSemaphoreSubmitInfo);
|
||||
DECLARE_DESERIALISE_TYPE(VkSemaphoreTypeCreateInfo);
|
||||
DECLARE_DESERIALISE_TYPE(VkSemaphoreWaitInfo);
|
||||
DECLARE_DESERIALISE_TYPE(VkShaderCreateInfoEXT);
|
||||
DECLARE_DESERIALISE_TYPE(VkShaderModuleCreateInfo);
|
||||
DECLARE_DESERIALISE_TYPE(VkShaderModuleValidationCacheCreateInfoEXT);
|
||||
DECLARE_DESERIALISE_TYPE(VkSharedPresentSurfaceCapabilitiesKHR);
|
||||
@@ -2309,6 +2315,8 @@ DECLARE_REFLECTION_ENUM(VkSamplerYcbcrRange);
|
||||
DECLARE_REFLECTION_ENUM(VkSemaphoreImportFlagBits);
|
||||
DECLARE_REFLECTION_ENUM(VkSemaphoreType);
|
||||
DECLARE_REFLECTION_ENUM(VkSemaphoreWaitFlagBits);
|
||||
DECLARE_REFLECTION_ENUM(VkShaderCodeTypeEXT);
|
||||
DECLARE_REFLECTION_ENUM(VkShaderCreateFlagBitsEXT);
|
||||
DECLARE_REFLECTION_ENUM(VkShaderFloatControlsIndependence);
|
||||
DECLARE_REFLECTION_ENUM(VkShaderStageFlagBits);
|
||||
DECLARE_REFLECTION_ENUM(VkSharingMode);
|
||||
|
||||
@@ -454,6 +454,10 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
|
||||
VkPhysicalDeviceShaderIntegerDotProductFeatures); \
|
||||
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES, \
|
||||
VkPhysicalDeviceShaderIntegerDotProductProperties); \
|
||||
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT, \
|
||||
VkPhysicalDeviceShaderObjectFeaturesEXT); \
|
||||
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_PROPERTIES_EXT, \
|
||||
VkPhysicalDeviceShaderObjectPropertiesEXT); \
|
||||
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES, \
|
||||
VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures) \
|
||||
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR, \
|
||||
@@ -1063,8 +1067,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MAXIMAL_RECONVERGENCE_FEATURES_KHR: \
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_FEATURES_EXT: \
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_PROPERTIES_EXT: \
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT: \
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_PROPERTIES_EXT: \
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_QUAD_CONTROL_FEATURES_KHR: \
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_FEATURES_NV: \
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_PROPERTIES_NV: \
|
||||
@@ -1134,7 +1136,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
|
||||
case VK_STRUCTURE_TYPE_SEMAPHORE_GET_ZIRCON_HANDLE_INFO_FUCHSIA: \
|
||||
case VK_STRUCTURE_TYPE_SET_DESCRIPTOR_BUFFER_OFFSETS_INFO_EXT: \
|
||||
case VK_STRUCTURE_TYPE_SET_LATENCY_MARKER_INFO_NV: \
|
||||
case VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT: \
|
||||
case VK_STRUCTURE_TYPE_SHADER_MODULE_IDENTIFIER_EXT: \
|
||||
case VK_STRUCTURE_TYPE_SUBPASS_SHADING_PIPELINE_CREATE_INFO_HUAWEI: \
|
||||
case VK_STRUCTURE_TYPE_SUBRESOURCE_HOST_MEMCPY_SIZE_EXT: \
|
||||
@@ -1561,6 +1562,14 @@ size_t GetNextPatchSize(const void *pNext)
|
||||
memSize += info->semaphoreCount * sizeof(VkSemaphore);
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT:
|
||||
{
|
||||
memSize += sizeof(VkShaderCreateInfoEXT);
|
||||
|
||||
VkShaderCreateInfoEXT *info = (VkShaderCreateInfoEXT *)next;
|
||||
memSize += info->setLayoutCount * sizeof(VkDescriptorSetLayout);
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_SUBMIT_INFO:
|
||||
{
|
||||
memSize += sizeof(VkSubmitInfo);
|
||||
@@ -2647,6 +2656,26 @@ void UnwrapNextChain(CaptureState state, const char *structName, byte *&tempMem,
|
||||
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT:
|
||||
{
|
||||
const VkShaderCreateInfoEXT *in = (const VkShaderCreateInfoEXT *)nextInput;
|
||||
VkShaderCreateInfoEXT *out = (VkShaderCreateInfoEXT *)tempMem;
|
||||
|
||||
// append immediately so tempMem is incremented
|
||||
AppendModifiedChainedStruct(tempMem, out, nextChainTail);
|
||||
|
||||
// allocate unwrapped array
|
||||
VkDescriptorSetLayout *outLayouts = (VkDescriptorSetLayout *)tempMem;
|
||||
tempMem += sizeof(VkDescriptorSetLayout) * in->setLayoutCount;
|
||||
|
||||
*out = *in;
|
||||
|
||||
out->pSetLayouts = outLayouts;
|
||||
for(uint32_t i = 0; i < in->setLayoutCount; i++)
|
||||
outLayouts[i] = Unwrap(in->pSetLayouts[i]);
|
||||
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_SUBMIT_INFO:
|
||||
{
|
||||
const VkSubmitInfo *in = (const VkSubmitInfo *)nextInput;
|
||||
@@ -3138,6 +3167,9 @@ void CopyNextChainForPatching(const char *structName, byte *&tempMem, VkBaseInSt
|
||||
case VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO:
|
||||
CopyNextChainedStruct(sizeof(VkSemaphoreWaitInfo), tempMem, nextInput, nextChainTail);
|
||||
break;
|
||||
case VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT:
|
||||
CopyNextChainedStruct(sizeof(VkShaderCreateInfoEXT), tempMem, nextInput, nextChainTail);
|
||||
break;
|
||||
case VK_STRUCTURE_TYPE_SUBMIT_INFO:
|
||||
CopyNextChainedStruct(sizeof(VkSubmitInfo), tempMem, nextInput, nextChainTail);
|
||||
break;
|
||||
|
||||
@@ -171,6 +171,7 @@ DECL_VKFLAG_EXT(VkAccelerationStructureCreate, KHR);
|
||||
DECL_VKFLAG_EXT(VkBuildAccelerationStructure, KHR);
|
||||
DECL_VKFLAG_EXT(VkGeometry, KHR);
|
||||
DECL_VKFLAG_EXT(VkGeometryInstance, KHR);
|
||||
DECL_VKFLAG_EXT(VkShaderCreate, EXT);
|
||||
|
||||
// serialise a member as flags - cast to the Bits enum for serialisation so the stringification
|
||||
// picks up the bitfield and doesn't treat it as uint32_t. Then we rename the type back to the base
|
||||
@@ -1348,6 +1349,13 @@ SERIALISE_VK_HANDLES();
|
||||
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES, \
|
||||
VkPhysicalDeviceShaderIntegerDotProductProperties) \
|
||||
\
|
||||
/* VK_EXT_shader_object*/ \
|
||||
PNEXT_STRUCT(VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT, VkShaderCreateInfoEXT) \
|
||||
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT, \
|
||||
VkPhysicalDeviceShaderObjectFeaturesEXT) \
|
||||
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_PROPERTIES_EXT, \
|
||||
VkPhysicalDeviceShaderObjectPropertiesEXT) \
|
||||
\
|
||||
/* VK_KHR_shader_subgroup_extended_types */ \
|
||||
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES, \
|
||||
VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures) \
|
||||
@@ -1659,11 +1667,6 @@ SERIALISE_VK_HANDLES();
|
||||
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_MODULE_IDENTIFIER_CREATE_INFO_EXT) \
|
||||
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_SHADER_MODULE_IDENTIFIER_EXT) \
|
||||
\
|
||||
/* VK_EXT_shader_object */ \
|
||||
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT) \
|
||||
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_PROPERTIES_EXT) \
|
||||
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT) \
|
||||
\
|
||||
/* VK_EXT_shader_tile_image */ \
|
||||
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TILE_IMAGE_FEATURES_EXT) \
|
||||
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TILE_IMAGE_PROPERTIES_EXT) \
|
||||
@@ -6567,6 +6570,81 @@ void Deserialise(const VkPhysicalDeviceExtendedDynamicState3PropertiesEXT &el)
|
||||
DeserialiseNext(el.pNext);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
void DoSerialise(SerialiserType &ser, VkShaderCreateInfoEXT &el)
|
||||
{
|
||||
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT);
|
||||
SerialiseNext(ser, el.sType, el.pNext);
|
||||
|
||||
SERIALISE_MEMBER_VKFLAGS(VkShaderCreateFlagsEXT, flags);
|
||||
SERIALISE_MEMBER(stage).Important();
|
||||
SERIALISE_MEMBER_VKFLAGS(VkShaderStageFlags, nextStage);
|
||||
SERIALISE_MEMBER(codeType);
|
||||
|
||||
// don't serialise size_t, otherwise capture/replay between different bit-ness won't work
|
||||
{
|
||||
uint64_t codeSize = el.codeSize;
|
||||
ser.Serialise("codeSize"_lit, codeSize);
|
||||
if(ser.IsReading())
|
||||
el.codeSize = (size_t)codeSize;
|
||||
}
|
||||
|
||||
// serialise as void* so it goes through as a buffer, not an actual array of integers.
|
||||
{
|
||||
const void *pCode = el.pCode;
|
||||
ser.Serialise("pCode"_lit, pCode, el.codeSize, SerialiserFlags::AllocateMemory);
|
||||
if(ser.IsReading())
|
||||
el.pCode = (uint32_t *)pCode;
|
||||
}
|
||||
|
||||
SERIALISE_MEMBER(pName).Important();
|
||||
SERIALISE_MEMBER(setLayoutCount);
|
||||
SERIALISE_MEMBER_ARRAY(pSetLayouts, setLayoutCount).Important();
|
||||
SERIALISE_MEMBER(pushConstantRangeCount).Important();
|
||||
SERIALISE_MEMBER_ARRAY(pPushConstantRanges, pushConstantRangeCount);
|
||||
SERIALISE_MEMBER_OPT(pSpecializationInfo);
|
||||
}
|
||||
|
||||
template <>
|
||||
void Deserialise(const VkShaderCreateInfoEXT &el)
|
||||
{
|
||||
DeserialiseNext(el.pNext);
|
||||
FreeAlignedBuffer((byte *)el.pCode);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
void DoSerialise(SerialiserType &ser, VkPhysicalDeviceShaderObjectFeaturesEXT &el)
|
||||
{
|
||||
RDCASSERT(ser.IsReading() ||
|
||||
el.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT);
|
||||
SerialiseNext(ser, el.sType, el.pNext);
|
||||
|
||||
SERIALISE_MEMBER(shaderObject);
|
||||
}
|
||||
|
||||
template <>
|
||||
void Deserialise(const VkPhysicalDeviceShaderObjectFeaturesEXT &el)
|
||||
{
|
||||
DeserialiseNext(el.pNext);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
void DoSerialise(SerialiserType &ser, VkPhysicalDeviceShaderObjectPropertiesEXT &el)
|
||||
{
|
||||
RDCASSERT(ser.IsReading() ||
|
||||
el.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_PROPERTIES_EXT);
|
||||
SerialiseNext(ser, el.sType, el.pNext);
|
||||
|
||||
SERIALISE_MEMBER(shaderBinaryUUID);
|
||||
SERIALISE_MEMBER(shaderBinaryVersion);
|
||||
}
|
||||
|
||||
template <>
|
||||
void Deserialise(const VkPhysicalDeviceShaderObjectPropertiesEXT &el)
|
||||
{
|
||||
DeserialiseNext(el.pNext);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
void DoSerialise(SerialiserType &ser, VkPhysicalDeviceFragmentDensityMapFeaturesEXT &el)
|
||||
{
|
||||
@@ -12425,6 +12503,8 @@ INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceShaderImageFootprintFeaturesNV);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceShaderIntegerDotProductFeatures);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceShaderIntegerDotProductProperties);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceShaderObjectFeaturesEXT);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceShaderObjectPropertiesEXT);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceShaderTerminateInvocationFeatures);
|
||||
@@ -12533,6 +12613,7 @@ INSTANTIATE_SERIALISE_TYPE(VkSemaphoreSignalInfo);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkSemaphoreSubmitInfo);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkSemaphoreTypeCreateInfo);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkSemaphoreWaitInfo);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkShaderCreateInfoEXT);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkShaderModuleCreateInfo);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkShaderModuleValidationCacheCreateInfoEXT);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkSharedPresentSurfaceCapabilitiesKHR);
|
||||
|
||||
@@ -3886,6 +3886,33 @@ rdcstr DoStringise(const VkPresentScalingFlagBitsEXT &el)
|
||||
END_BITFIELD_STRINGISE();
|
||||
}
|
||||
|
||||
template <>
|
||||
rdcstr DoStringise(const VkShaderCodeTypeEXT &el)
|
||||
{
|
||||
BEGIN_ENUM_STRINGISE(VkShaderCodeTypeEXT);
|
||||
{
|
||||
STRINGISE_ENUM(VK_SHADER_CODE_TYPE_BINARY_EXT);
|
||||
STRINGISE_ENUM(VK_SHADER_CODE_TYPE_SPIRV_EXT);
|
||||
}
|
||||
END_ENUM_STRINGISE();
|
||||
}
|
||||
|
||||
template <>
|
||||
rdcstr DoStringise(const VkShaderCreateFlagBitsEXT &el)
|
||||
{
|
||||
BEGIN_BITFIELD_STRINGISE(VkShaderCreateFlagBitsEXT);
|
||||
{
|
||||
STRINGISE_BITFIELD_BIT(VK_SHADER_CREATE_LINK_STAGE_BIT_EXT);
|
||||
STRINGISE_BITFIELD_BIT(VK_SHADER_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT);
|
||||
STRINGISE_BITFIELD_BIT(VK_SHADER_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT);
|
||||
STRINGISE_BITFIELD_BIT(VK_SHADER_CREATE_NO_TASK_SHADER_BIT_EXT);
|
||||
STRINGISE_BITFIELD_BIT(VK_SHADER_CREATE_DISPATCH_BASE_BIT_EXT);
|
||||
STRINGISE_BITFIELD_BIT(VK_SHADER_CREATE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_EXT);
|
||||
STRINGISE_BITFIELD_BIT(VK_SHADER_CREATE_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT);
|
||||
}
|
||||
END_BITFIELD_STRINGISE();
|
||||
}
|
||||
|
||||
template <>
|
||||
rdcstr DoStringise(const VkExtent3D &el)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user