Skip to content
Snippets Groups Projects
Commit dda8de09 authored by Artur Wasmut's avatar Artur Wasmut
Browse files

[#105] add ugly pbr grass textures for testing. Implement ugly variable...

[#105] add ugly pbr grass textures for testing. Implement ugly variable descriptor count extensions.
parent 28a0a425
Branches
Tags
1 merge request!88Resolve "Indirect Draw"
Showing
with 151 additions and 21 deletions
...@@ -41,12 +41,14 @@ namespace vkcv ...@@ -41,12 +41,14 @@ namespace vkcv
uint32_t bindingID, uint32_t bindingID,
DescriptorType descriptorType, DescriptorType descriptorType,
uint32_t descriptorCount, uint32_t descriptorCount,
ShaderStage shaderStage ShaderStage shaderStage,
bool variableCount = false
) noexcept; ) noexcept;
uint32_t bindingID; uint32_t bindingID;
DescriptorType descriptorType; DescriptorType descriptorType;
uint32_t descriptorCount; uint32_t descriptorCount;
ShaderStage shaderStage; ShaderStage shaderStage;
bool variableCount;
}; };
} }
...@@ -4,12 +4,13 @@ ...@@ -4,12 +4,13 @@
namespace vkcv { namespace vkcv {
struct SampledImageDescriptorWrite { struct SampledImageDescriptorWrite {
inline SampledImageDescriptorWrite(uint32_t binding, ImageHandle image, uint32_t mipLevel = 0, bool useGeneralLayout = false) inline SampledImageDescriptorWrite(uint32_t binding, ImageHandle image, uint32_t mipLevel = 0, bool useGeneralLayout = false, uint32_t arrayIndex = 0)
: binding(binding), image(image), mipLevel(mipLevel), useGeneralLayout(useGeneralLayout) {}; : binding(binding), image(image), mipLevel(mipLevel), useGeneralLayout(useGeneralLayout), arrayIndex(arrayIndex) {};
uint32_t binding; uint32_t binding;
ImageHandle image; ImageHandle image;
uint32_t mipLevel; uint32_t mipLevel;
bool useGeneralLayout; bool useGeneralLayout;
uint32_t arrayIndex;
}; };
struct StorageImageDescriptorWrite { struct StorageImageDescriptorWrite {
......
projects/bindless_textures/resources/cube/Grass001_1K_AmbientOcclusion.jpg

131 B

projects/bindless_textures/resources/cube/Grass001_1K_Color.jpg

132 B

projects/bindless_textures/resources/cube/Grass001_1K_Displacement.jpg

131 B

projects/bindless_textures/resources/cube/Grass001_1K_Normal.jpg

132 B

projects/bindless_textures/resources/cube/Grass001_1K_Roughness.jpg

131 B

...@@ -4,12 +4,13 @@ ...@@ -4,12 +4,13 @@
layout(location = 0) in vec3 passNormal; layout(location = 0) in vec3 passNormal;
layout(location = 1) in vec2 passUV; layout(location = 1) in vec2 passUV;
layout(location = 2) in flat int passTextureIndex;
layout(location = 0) out vec3 outColor; layout(location = 0) out vec3 outColor;
layout(set=0, binding=0) uniform texture2D materialTextures[]; layout(set=0, binding=0) uniform sampler textureSampler;
layout(set=0, binding=1) uniform sampler textureSampler; layout(set=0, binding=1) uniform texture2D materialTextures[];
void main() { void main() {
outColor = texture(sampler2D(materialTextures[1], textureSampler), passUV).rgb; outColor = texture(sampler2D(materialTextures[passTextureIndex], textureSampler), passUV).rgb;
} }
\ No newline at end of file
...@@ -7,13 +7,33 @@ layout(location = 2) in vec2 inUV; ...@@ -7,13 +7,33 @@ layout(location = 2) in vec2 inUV;
layout(location = 0) out vec3 passNormal; layout(location = 0) out vec3 passNormal;
layout(location = 1) out vec2 passUV; layout(location = 1) out vec2 passUV;
layout(location = 2) out flat int passTextureIndex;
layout( push_constant ) uniform constants{ layout( push_constant ) uniform constants{
mat4 mvp; mat4 mvp;
}; };
void main() { void main()
{
gl_Position = mvp * vec4(inPosition, 1.0); gl_Position = mvp * vec4(inPosition, 1.0);
passNormal = inNormal; passNormal = inNormal;
passUV = inUV; passUV = inUV;
if(inNormal.x > 0.9)
passTextureIndex = 0;
if(inNormal.x < -0.9)
passTextureIndex = 1;
if(inNormal.y > 0.9)
passTextureIndex = 2;
if(inNormal.y < -0.9)
passTextureIndex = 3;
if(inNormal.z > 0.9)
passTextureIndex = 4;
if(inNormal.z < -0.9)
passTextureIndex = 5;
} }
\ No newline at end of file
...@@ -30,6 +30,26 @@ int main(int argc, const char** argv) { ...@@ -30,6 +30,26 @@ int main(int argc, const char** argv) {
vkcv::asset::Scene mesh; vkcv::asset::Scene mesh;
// TEST DATA
std::vector<vkcv::Image> texturesArray;
const std::string grassPaths[5] = { "resources/cube/Grass001_1K_AmbientOcclusion.jpg",
"resources/cube/Grass001_1K_Color.jpg",
"resources/cube/Grass001_1K_Displacement.jpg",
"resources/cube/Grass001_1K_Normal.jpg",
"resources/cube/Grass001_1K_Roughness.jpg" };
for(uint32_t i = 0; i < 5; i++)
{
std::filesystem::path grassPath(grassPaths[i]);
vkcv::asset::TextureData grassTexture = vkcv::asset::loadTexture(grassPath);
vkcv::Image texture = core.createImage(vk::Format::eR8G8B8A8Srgb, grassTexture.width, grassTexture.height);
texture.fill(grassTexture.data.data());
texture.generateMipChainImmediate();
texture.switchLayout(vk::ImageLayout::eShaderReadOnlyOptimal);
texturesArray.push_back(texture);
}
const char* path = argc > 1 ? argv[1] : "resources/cube/cube.gltf"; const char* path = argc > 1 ? argv[1] : "resources/cube/cube.gltf";
int result = vkcv::asset::loadScene(path, mesh); int result = vkcv::asset::loadScene(path, mesh);
...@@ -135,6 +155,7 @@ int main(int argc, const char** argv) { ...@@ -135,6 +155,7 @@ int main(int argc, const char** argv) {
texture.fill(tex.data.data()); texture.fill(tex.data.data());
texture.generateMipChainImmediate(); texture.generateMipChainImmediate();
texture.switchLayout(vk::ImageLayout::eShaderReadOnlyOptimal); texture.switchLayout(vk::ImageLayout::eShaderReadOnlyOptimal);
texturesArray.push_back(texture);
vkcv::SamplerHandle sampler = core.createSampler( vkcv::SamplerHandle sampler = core.createSampler(
vkcv::SamplerFilterType::LINEAR, vkcv::SamplerFilterType::LINEAR,
...@@ -149,8 +170,18 @@ int main(int argc, const char** argv) { ...@@ -149,8 +170,18 @@ int main(int argc, const char** argv) {
vkcv::VertexBufferBinding(static_cast<vk::DeviceSize>(attributes[2].offset), vertexBuffer.getVulkanHandle()) }; vkcv::VertexBufferBinding(static_cast<vk::DeviceSize>(attributes[2].offset), vertexBuffer.getVulkanHandle()) };
vkcv::DescriptorWrites setWrites; vkcv::DescriptorWrites setWrites;
setWrites.sampledImageWrites = { vkcv::SampledImageDescriptorWrite(0, texture.getHandle()) }; std::vector<vkcv::SampledImageDescriptorWrite> texturesArrayWrites;
setWrites.samplerWrites = { vkcv::SamplerDescriptorWrite(1, sampler) }; for(uint32_t i = 0; i < 6; i++)
{
texturesArrayWrites.push_back(vkcv::SampledImageDescriptorWrite(1,
texturesArray[i].getHandle(),
0,
false,
i));
}
setWrites.sampledImageWrites = texturesArrayWrites;
setWrites.samplerWrites = { vkcv::SamplerDescriptorWrite(0, sampler) };
core.writeDescriptorSet(descriptorSet, setWrites); core.writeDescriptorSet(descriptorSet, setWrites);
......
...@@ -325,6 +325,7 @@ namespace vkcv ...@@ -325,6 +325,7 @@ namespace vkcv
// NOTE: what about // NOTE: what about
// shaderSampledImageArrayNonUniformIndexing ? // shaderSampledImageArrayNonUniformIndexing ?
descriptorIndexingFeatures.descriptorBindingPartiallyBound = true; descriptorIndexingFeatures.descriptorBindingPartiallyBound = true;
descriptorIndexingFeatures.descriptorBindingVariableDescriptorCount = true;
descriptorIndexingFeatures.runtimeDescriptorArray = true; descriptorIndexingFeatures.runtimeDescriptorArray = true;
deviceFeatures2.setPNext(&descriptorIndexingFeatures); deviceFeatures2.setPNext(&descriptorIndexingFeatures);
} }
......
...@@ -5,11 +5,13 @@ namespace vkcv { ...@@ -5,11 +5,13 @@ namespace vkcv {
uint32_t bindingID, uint32_t bindingID,
DescriptorType descriptorType, DescriptorType descriptorType,
uint32_t descriptorCount, uint32_t descriptorCount,
ShaderStage shaderStage) noexcept ShaderStage shaderStage,
bool variableCount) noexcept
: :
bindingID(bindingID), bindingID(bindingID),
descriptorType(descriptorType), descriptorType(descriptorType),
descriptorCount(descriptorCount), descriptorCount(descriptorCount),
shaderStage(shaderStage) {} shaderStage(shaderStage),
variableCount(variableCount){}
} }
...@@ -48,20 +48,46 @@ namespace vkcv ...@@ -48,20 +48,46 @@ namespace vkcv
{ {
std::vector<vk::DescriptorSetLayoutBinding> setBindings = {}; std::vector<vk::DescriptorSetLayoutBinding> setBindings = {};
//create each set's binding // When using a variable descriptor count, the reflected bindings' descriptorCount value is 0.
for (auto binding : bindings) { // However, a proper value has to be specified. Problem is, this value still counts towards Vulkan's limits,
// which is why we can't really use something like UINT32_MAX. So, 128 has been chosen.
const uint32_t variableDescriptorCountLimit = 128;
//create set's bindings
for (auto binding : bindings)
{
vk::DescriptorSetLayoutBinding descriptorSetLayoutBinding( vk::DescriptorSetLayoutBinding descriptorSetLayoutBinding(
binding.bindingID, binding.bindingID,
convertDescriptorTypeFlag(binding.descriptorType), convertDescriptorTypeFlag(binding.descriptorType),
binding.descriptorCount, binding.descriptorCount,
convertShaderStageFlag(binding.shaderStage)); convertShaderStageFlag(binding.shaderStage));
if(binding.variableCount)
// magic number
descriptorSetLayoutBinding.descriptorCount = variableDescriptorCountLimit;
setBindings.push_back(descriptorSetLayoutBinding); setBindings.push_back(descriptorSetLayoutBinding);
} }
DescriptorSet set; std::vector<vk::DescriptorBindingFlags> bindingFlags;
// create binding flags
//create the descriptor set's layout from the bindings gathered above for (auto binding : bindings)
{
if (binding.variableCount)
{
bindingFlags.push_back(vk::DescriptorBindingFlagBitsEXT::eVariableDescriptorCount |
vk::DescriptorBindingFlagBitsEXT::ePartiallyBound);
} else
{
bindingFlags.push_back({});
}
}
vk::DescriptorSetLayoutBindingFlagsCreateInfo bindingFlagsInfo(static_cast<uint32_t>(bindingFlags.size()), bindingFlags.data());
//create the descriptor set's layout from the binding and flag information gathered above
vk::DescriptorSetLayoutCreateInfo layoutInfo({}, setBindings); vk::DescriptorSetLayoutCreateInfo layoutInfo({}, setBindings);
layoutInfo.setPNext(&bindingFlagsInfo);
DescriptorSet set;
if (m_Device.createDescriptorSetLayout(&layoutInfo, nullptr, &set.layout) != vk::Result::eSuccess) { if (m_Device.createDescriptorSetLayout(&layoutInfo, nullptr, &set.layout) != vk::Result::eSuccess) {
vkcv_log(LogLevel::ERROR, "Failed to create descriptor set layout"); vkcv_log(LogLevel::ERROR, "Failed to create descriptor set layout");
return DescriptorSetHandle(); return DescriptorSetHandle();
...@@ -69,6 +95,9 @@ namespace vkcv ...@@ -69,6 +95,9 @@ namespace vkcv
//create and allocate the set based on the layout that have been gathered above //create and allocate the set based on the layout that have been gathered above
vk::DescriptorSetAllocateInfo allocInfo(m_Pools.back(), 1, &set.layout); vk::DescriptorSetAllocateInfo allocInfo(m_Pools.back(), 1, &set.layout);
vk::DescriptorSetVariableDescriptorCountAllocateInfo variableAllocInfo = {1, &variableDescriptorCountLimit};
allocInfo.setPNext(&variableAllocInfo);
auto result = m_Device.allocateDescriptorSets(&allocInfo, &set.vulkanHandle); auto result = m_Device.allocateDescriptorSets(&allocInfo, &set.vulkanHandle);
if(result != vk::Result::eSuccess) if(result != vk::Result::eSuccess)
{ {
...@@ -100,6 +129,7 @@ namespace vkcv ...@@ -100,6 +129,7 @@ namespace vkcv
size_t imageInfoIndex; size_t imageInfoIndex;
size_t bufferInfoIndex; size_t bufferInfoIndex;
uint32_t binding; uint32_t binding;
uint32_t arrayElementIndex;
vk::DescriptorType type; vk::DescriptorType type;
}; };
...@@ -116,7 +146,8 @@ namespace vkcv ...@@ -116,7 +146,8 @@ namespace vkcv
std::vector<WriteDescriptorSetInfo> writeInfos; std::vector<WriteDescriptorSetInfo> writeInfos;
for (const auto& write : writes.sampledImageWrites) { for (const auto& write : writes.sampledImageWrites)
{
vk::ImageLayout layout = write.useGeneralLayout ? vk::ImageLayout::eGeneral : vk::ImageLayout::eShaderReadOnlyOptimal; vk::ImageLayout layout = write.useGeneralLayout ? vk::ImageLayout::eGeneral : vk::ImageLayout::eShaderReadOnlyOptimal;
const vk::DescriptorImageInfo imageInfo( const vk::DescriptorImageInfo imageInfo(
nullptr, nullptr,
...@@ -130,6 +161,7 @@ namespace vkcv ...@@ -130,6 +161,7 @@ namespace vkcv
imageInfos.size(), imageInfos.size(),
0, 0,
write.binding, write.binding,
write.arrayIndex,
vk::DescriptorType::eSampledImage, vk::DescriptorType::eSampledImage,
}; };
...@@ -149,6 +181,7 @@ namespace vkcv ...@@ -149,6 +181,7 @@ namespace vkcv
imageInfos.size(), imageInfos.size(),
0, 0,
write.binding, write.binding,
0,
vk::DescriptorType::eStorageImage vk::DescriptorType::eStorageImage
}; };
...@@ -173,6 +206,7 @@ namespace vkcv ...@@ -173,6 +206,7 @@ namespace vkcv
0, 0,
bufferInfos.size(), bufferInfos.size(),
write.binding, write.binding,
0,
write.dynamic? write.dynamic?
vk::DescriptorType::eUniformBufferDynamic : vk::DescriptorType::eUniformBufferDynamic :
vk::DescriptorType::eUniformBuffer vk::DescriptorType::eUniformBuffer
...@@ -199,6 +233,7 @@ namespace vkcv ...@@ -199,6 +233,7 @@ namespace vkcv
0, 0,
bufferInfos.size(), bufferInfos.size(),
write.binding, write.binding,
0,
write.dynamic? write.dynamic?
vk::DescriptorType::eStorageBufferDynamic : vk::DescriptorType::eStorageBufferDynamic :
vk::DescriptorType::eStorageBuffer vk::DescriptorType::eStorageBuffer
...@@ -222,6 +257,7 @@ namespace vkcv ...@@ -222,6 +257,7 @@ namespace vkcv
imageInfos.size(), imageInfos.size(),
0, 0,
write.binding, write.binding,
0,
vk::DescriptorType::eSampler vk::DescriptorType::eSampler
}; };
...@@ -234,7 +270,7 @@ namespace vkcv ...@@ -234,7 +270,7 @@ namespace vkcv
vk::WriteDescriptorSet vulkanWrite( vk::WriteDescriptorSet vulkanWrite(
set, set,
write.binding, write.binding,
static_cast<uint32_t>(0), write.arrayElementIndex,
1, 1,
write.type, write.type,
(write.imageInfoIndex > 0? &(imageInfos[write.imageInfoIndex - 1]) : nullptr), (write.imageInfoIndex > 0? &(imageInfos[write.imageInfoIndex - 1]) : nullptr),
......
...@@ -175,12 +175,33 @@ namespace vkcv { ...@@ -175,12 +175,33 @@ namespace vkcv {
for (uint32_t i = 0; i < resources.separate_images.size(); i++) { for (uint32_t i = 0; i < resources.separate_images.size(); i++) {
auto& u = resources.separate_images[i]; auto& u = resources.separate_images[i];
const spirv_cross::SPIRType& base_type = comp.get_type(u.base_type_id); const spirv_cross::SPIRType& base_type = comp.get_type(u.base_type_id);
std::pair descriptor(comp.get_decoration(u.id, spv::DecorationDescriptorSet),
DescriptorBinding(comp.get_decoration(u.id, spv::DecorationBinding), DescriptorType::IMAGE_SAMPLED, base_type.vecsize, shaderStage)); // we require the type (not base type!) to query array information
const spirv_cross::SPIRType& type = comp.get_type(u.type_id);
uint32_t descriptorCount = 1;
bool variableCount = false;
if(type.array_size_literal[0])
{
if(type.array[0] == 0)
variableCount = true;
descriptorCount = type.array[0];
}
DescriptorBinding descBinding(comp.get_decoration(u.id, spv::DecorationBinding),
DescriptorType::IMAGE_SAMPLED,
descriptorCount,
shaderStage,
variableCount);
std::pair<uint32_t, DescriptorBinding> descriptor(comp.get_decoration(u.id, spv::DecorationDescriptorSet), descBinding);
bindings.push_back(descriptor); bindings.push_back(descriptor);
if ((int32_t)comp.get_decoration(u.id, spv::DecorationDescriptorSet) > maxSetID) if ((int32_t)comp.get_decoration(u.id, spv::DecorationDescriptorSet) > maxSetID)
maxSetID = comp.get_decoration(u.id, spv::DecorationDescriptorSet); maxSetID = comp.get_decoration(u.id, spv::DecorationDescriptorSet);
} }
for (uint32_t i = 0; i < resources.storage_images.size(); i++) { for (uint32_t i = 0; i < resources.storage_images.size(); i++) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment