mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-30 14:42:56 +02:00
Vulkan texture binding fixes, cubemap support
This commit is contained in:
parent
602caa88ce
commit
fb5651a30b
5 changed files with 218 additions and 63 deletions
libraries
|
@ -267,6 +267,7 @@ struct Cache {
|
|||
return result;
|
||||
}
|
||||
|
||||
// VKTODO: This needs to be used instead of getPipeline
|
||||
// Returns structure containing pipeline layout and descriptor set layouts
|
||||
PipelineLayout getPipelineAndDescriptorLayout(const vks::Context& context) {
|
||||
auto itr = _layoutMap.find(pipeline);
|
||||
|
@ -474,6 +475,7 @@ struct Cache {
|
|||
}
|
||||
|
||||
VkPipeline getPipeline(const vks::Context& context) {
|
||||
//VKTODO: pipelines are not cached here currently
|
||||
auto renderpass = pipelineState.getRenderPass(context);
|
||||
auto pipelineLayout = pipelineState.getPipelineAndDescriptorLayout(context);
|
||||
const gpu::Pipeline& pipeline = *gpu::acquire(pipelineState.pipeline);
|
||||
|
@ -523,8 +525,8 @@ struct Cache {
|
|||
//float ra.depthBiasConstantFactor;
|
||||
//float ra.depthBiasClamp;
|
||||
//float ra.depthBiasSlopeFactor;
|
||||
ra.depthClampEnable = VK_TRUE;
|
||||
//ra.depthClampEnable = stateData.flags.depthClampEnable ? VK_TRUE : VK_FALSE; // VKTODO
|
||||
//ra.depthClampEnable = VK_TRUE;
|
||||
ra.depthClampEnable = stateData.flags.depthClampEnable ? VK_TRUE : VK_FALSE; // VKTODO
|
||||
ra.frontFace = stateData.flags.frontFaceClockwise ? VK_FRONT_FACE_CLOCKWISE : VK_FRONT_FACE_COUNTER_CLOCKWISE;
|
||||
// ra.lineWidth
|
||||
ra.polygonMode = (VkPolygonMode)(2 - stateData.fillMode);
|
||||
|
@ -551,8 +553,8 @@ struct Cache {
|
|||
// Depth/Stencil
|
||||
{
|
||||
auto& ds = builder.depthStencilState;
|
||||
ds.depthTestEnable = VK_FALSE;
|
||||
//ds.depthTestEnable = stateData.depthTest.isEnabled() ? VK_TRUE : VK_FALSE; //VKTODO
|
||||
//ds.depthTestEnable = VK_FALSE;
|
||||
ds.depthTestEnable = stateData.depthTest.isEnabled() ? VK_TRUE : VK_FALSE; //VKTODO
|
||||
ds.depthWriteEnable = stateData.depthTest.getWriteMask() != 0 ? VK_TRUE : VK_FALSE;
|
||||
ds.depthCompareOp = (VkCompareOp)stateData.depthTest.getFunction();
|
||||
ds.front = getStencilOp(stateData.stencilTestFront);
|
||||
|
@ -598,8 +600,9 @@ struct Cache {
|
|||
// Explicitly add the draw call info slot if required
|
||||
if (vertexReflection.validInput(gpu::slot::attr::DrawCallInfo)) {
|
||||
ad.push_back(
|
||||
{ gpu::slot::attr::DrawCallInfo, gpu::slot::attr::DrawCallInfo, VK_FORMAT_R32G32_SINT, (uint32_t)0 });
|
||||
bd.push_back({ gpu::slot::attr::DrawCallInfo, (uint32_t)sizeof(uint16_t) * 2, VK_VERTEX_INPUT_RATE_VERTEX });
|
||||
{ gpu::slot::attr::DrawCallInfo, gpu::slot::attr::DrawCallInfo, VK_FORMAT_R16G16_SINT, (uint32_t)0 });
|
||||
//bd.push_back({ gpu::slot::attr::DrawCallInfo, (uint32_t)sizeof(uint16_t) * 2, VK_VERTEX_INPUT_RATE_VERTEX });
|
||||
bd.push_back({ gpu::slot::attr::DrawCallInfo, 0, VK_VERTEX_INPUT_RATE_VERTEX });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -621,10 +624,16 @@ void VKBackend::executeFrame(const FramePointer& frame) {
|
|||
{
|
||||
const auto& commandBuffer = _currentCommandBuffer;
|
||||
for (const auto& batchPtr : frame->batches) {
|
||||
if (batch_count == 6) {//12
|
||||
/*if (batch_count == 6) {//12
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
const auto& batch = *batchPtr;
|
||||
if (batch.getName() == "CompositeHUD") {
|
||||
continue; // VKTODO: crashes frame player currently
|
||||
}
|
||||
if (batch.getName() == "Resample::run") {
|
||||
continue; // VKTODO: no framebuffer commands support yet
|
||||
}
|
||||
cmdBeginLabel(commandBuffer, "batch:" + batch.getName(), glm::vec4{ 1, 1, 0, 1 });
|
||||
const auto& commands = batch.getCommands();
|
||||
const auto& offsets = batch.getCommandOffsets();
|
||||
|
@ -990,12 +999,23 @@ void VKBackend::setCameraCorrection(const Mat4& correction, const Mat4& prevRend
|
|||
}
|
||||
|
||||
void VKBackend::updateVkDescriptorWriteSetsUniform(VkDescriptorSet target) {
|
||||
// VKTODO: can be used for "verification mode" later
|
||||
// VKTODO: it looks like renderer tends to bind buffers that should not be bound at given point? Or maybe I'm missing reset somewhere
|
||||
auto pipeline = gpu::acquire(_cache.pipelineState.pipeline);
|
||||
auto program = pipeline->getProgram();
|
||||
const auto& vertexReflection = program->getShaders()[0]->getReflection();
|
||||
const auto& fragmentReflection = program->getShaders()[1]->getReflection();
|
||||
|
||||
auto bindingMap = Cache::Pipeline::getBindingMap(vertexReflection.uniformBuffers, fragmentReflection.uniformBuffers);
|
||||
|
||||
std::vector<VkWriteDescriptorSet> sets;
|
||||
std::vector<VkDescriptorBufferInfo> bufferInfos;
|
||||
sets.reserve(_uniform._buffers.size());
|
||||
bufferInfos.reserve(_uniform._buffers.size()); // This is to avoid vector reallocation and changing pointer adresses
|
||||
for (size_t i = 0; i < _uniform._buffers.size(); i++) {
|
||||
if (_uniform._buffers[i].buffer || _uniform._buffers[i].vksBuffer) {
|
||||
if ((_uniform._buffers[i].buffer || _uniform._buffers[i].vksBuffer)
|
||||
&& (vertexReflection.validUniformBuffer(i) || fragmentReflection.validUniformBuffer(i))) {
|
||||
|
||||
// These cannot be set at the same time
|
||||
Q_ASSERT(!(_uniform._buffers[i].buffer && _uniform._buffers[i].vksBuffer));
|
||||
// VKTODO: move vulkan buffer creation to the transfer parts and aggregate several buffers together maybe?
|
||||
|
@ -1025,24 +1045,36 @@ void VKBackend::updateVkDescriptorWriteSetsUniform(VkDescriptorSet target) {
|
|||
}
|
||||
|
||||
void VKBackend::updateVkDescriptorWriteSetsTexture(VkDescriptorSet target) {
|
||||
// VKTODO: renderer leaves unbound texture slots, and that's not allowed on Vulkan
|
||||
// VKTODO: can be used for "verification mode" later
|
||||
// VKTODO: it looks like renderer tends to bind buffers that should not be bound at given point? Or maybe I'm missing reset somewhere
|
||||
auto pipeline = gpu::acquire(_cache.pipelineState.pipeline);
|
||||
auto program = pipeline->getProgram();
|
||||
const auto& vertexReflection = program->getShaders()[0]->getReflection();
|
||||
const auto& fragmentReflection = program->getShaders()[1]->getReflection();
|
||||
|
||||
auto bindingMap = Cache::Pipeline::getBindingMap(vertexReflection.textures, fragmentReflection.textures);
|
||||
|
||||
std::vector<VkWriteDescriptorSet> sets;
|
||||
std::vector<VkDescriptorImageInfo> imageInfos;
|
||||
sets.reserve(_uniform._buffers.size());
|
||||
imageInfos.reserve(_uniform._buffers.size()); // This is to avoid vector reallocation and changing pointer adresses
|
||||
for (size_t i = 0; i < _resource._textures.size(); i++) {
|
||||
if (_resource._textures[i].texture) {
|
||||
if (_resource._textures[i].texture && (vertexReflection.validTexture(i) || fragmentReflection.validTexture(i))) {
|
||||
// VKTODO: move vulkan texture creation to the transfer parts
|
||||
// VKTODO: this doesn't work yet
|
||||
VKTexture *texture = syncGPUObject(*_resource._textures[i].texture);
|
||||
VKTexture* texture = syncGPUObject(*_resource._textures[i].texture);
|
||||
VkDescriptorImageInfo imageInfo{};
|
||||
if (texture) {
|
||||
qDebug() << "Writing descriptor " << i << " with texture: " << _resource._textures[i].texture->source();
|
||||
imageInfo = texture->getDescriptorImageInfo();
|
||||
} else {
|
||||
if (_resource._textures[i].texture) {
|
||||
qDebug() << "Cannot sync texture during descriptor " << i << " write: " << _resource._textures[i].texture->source();
|
||||
qDebug() << "Cannot sync texture during descriptor " << i
|
||||
<< " write: " << _resource._textures[i].texture->source();
|
||||
} else {
|
||||
qDebug() << "Texture is null during descriptor " << i << " write: " << _resource._textures[i].texture->source();
|
||||
qDebug() << "Texture is null during descriptor " << i
|
||||
<< " write: " << _resource._textures[i].texture->source();
|
||||
}
|
||||
imageInfo = _defaultTexture.descriptor;
|
||||
}
|
||||
|
@ -1060,18 +1092,43 @@ void VKBackend::updateVkDescriptorWriteSetsTexture(VkDescriptorSet target) {
|
|||
descriptorWriteSet.descriptorCount = 1;
|
||||
descriptorWriteSet.pImageInfo = &imageInfos.back();
|
||||
sets.push_back(descriptorWriteSet);
|
||||
} else {
|
||||
auto binding = bindingMap.find(i);
|
||||
if (binding != bindingMap.end()) {
|
||||
// VKTODO: fill unbound but needed slots with default texture
|
||||
VkWriteDescriptorSet descriptorWriteSet{};
|
||||
descriptorWriteSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
descriptorWriteSet.dstSet = target;
|
||||
descriptorWriteSet.dstBinding = i;
|
||||
descriptorWriteSet.dstArrayElement = 0;
|
||||
descriptorWriteSet.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
descriptorWriteSet.descriptorCount = 1;
|
||||
descriptorWriteSet.pImageInfo = &_defaultTexture.descriptor;
|
||||
sets.push_back(descriptorWriteSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
vkUpdateDescriptorSets(_context.device->logicalDevice, sets.size(), sets.data(), 0, nullptr);
|
||||
}
|
||||
|
||||
void VKBackend::updateVkDescriptorWriteSetsStorage(VkDescriptorSet target) {
|
||||
// VKTODO: can be used for "verification mode" later
|
||||
// VKTODO: it looks like renderer tends to bind buffers that should not be bound at given point? Or maybe I'm missing reset somewhere
|
||||
auto pipeline = gpu::acquire(_cache.pipelineState.pipeline);
|
||||
auto program = pipeline->getProgram();
|
||||
const auto& vertexReflection = program->getShaders()[0]->getReflection();
|
||||
const auto& fragmentReflection = program->getShaders()[1]->getReflection();
|
||||
|
||||
auto bindingMap = Cache::Pipeline::getBindingMap(vertexReflection.resourceBuffers, fragmentReflection.resourceBuffers);
|
||||
|
||||
std::vector<VkWriteDescriptorSet> sets;
|
||||
std::vector<VkDescriptorBufferInfo> bufferInfos;
|
||||
sets.reserve(_uniform._buffers.size());
|
||||
bufferInfos.reserve(_uniform._buffers.size()); // This is to avoid vector reallocation and changing pointer adresses
|
||||
for (size_t i = 0; i < _resource._buffers.size(); i++) {
|
||||
if (_resource._buffers[i].buffer || _resource._buffers[i].vksBuffer) {
|
||||
if ((_resource._buffers[i].buffer || _resource._buffers[i].vksBuffer)
|
||||
&& (vertexReflection.validUniformBuffer(i) || fragmentReflection.validUniformBuffer(i))) {
|
||||
|
||||
Q_ASSERT(!(_resource._buffers[i].buffer && _resource._buffers[i].vksBuffer));
|
||||
// VKTODO: move vulkan buffer creation to the transfer parts and aggregate several buffers together maybe?
|
||||
VkDescriptorBufferInfo bufferInfo{};
|
||||
|
@ -1489,8 +1546,11 @@ VKTexture* VKBackend::syncGPUObject(const Texture& texture) {
|
|||
#endif
|
||||
case TextureUsageType::STRICT_RESOURCE:
|
||||
|
||||
if (texture.getStoredSize() == 0){
|
||||
// Stored size can sometimes be reported as 0 for valid textures.
|
||||
if (texture.getStoredSize() == 0 && texture.getStoredMipFormat() == gpu::Element()){
|
||||
qDebug(gpu_vk_logging) << "No data on texture";
|
||||
texture.getStoredMipFormat();
|
||||
texture.getStoredSize();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -1688,16 +1748,16 @@ void VKBackend::createDescriptorPool() {
|
|||
}
|
||||
|
||||
void VKBackend::initDefaultTexture() {
|
||||
int width = 256;
|
||||
int height = 256;
|
||||
int width = 1;
|
||||
int height = 1;
|
||||
std::vector<uint8_t> buffer;
|
||||
buffer.resize(width * height * 4);
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
buffer[x + y * width] = x;
|
||||
buffer[x + y * width + 1] = y;
|
||||
buffer[x + y * width + 2] = x + y;
|
||||
buffer[x + y * width + 3] = x - y;
|
||||
buffer[x + y * width] = 0;
|
||||
buffer[x + y * width + 1] = 0;
|
||||
buffer[x + y * width + 2] = 0;
|
||||
buffer[x + y * width + 3] = 255;
|
||||
}
|
||||
}
|
||||
_defaultTexture.fromBuffer(buffer.data(), buffer.size(), VK_FORMAT_R8G8B8A8_SRGB, width, height, _context.device.get(), _context.transferQueue);
|
||||
|
@ -1729,6 +1789,7 @@ void VKBackend::updateTransform(const gpu::Batch& batch) {
|
|||
// VKTODO
|
||||
// Since Vulkan has no glVertexAttrib equivalent we need to pass a buffer pointer here
|
||||
//glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, drawCallInfo.index, drawCallInfo.unused);
|
||||
qDebug() << "drawCallInfo.unused: " << drawCallInfoBuffer[_currentDraw].unused;
|
||||
// Draw call info for unnamed calls starts at the beginning of the buffer, with offset dependent on _currentDraw
|
||||
VkDeviceSize vkOffset = _currentDraw * sizeof(gpu::Batch::DrawCallInfo);
|
||||
vkCmdBindVertexBuffers(_currentCommandBuffer, gpu::Stream::DRAW_CALL_INFO, 1, &_transform._drawCallInfoBuffer->buffer, &vkOffset);
|
||||
|
@ -2325,6 +2386,7 @@ void VKBackend::do_setViewTransform(const Batch& batch, size_t paramOffset) {
|
|||
|
||||
void VKBackend::do_setProjectionTransform(const Batch& batch, size_t paramOffset) {
|
||||
memcpy(glm::value_ptr(_transform._projection), batch.readData(batch._params[paramOffset]._uint), sizeof(Mat4));
|
||||
_transform._projection = glm::scale(_transform._projection, glm::vec3(1.0f, -1.0f, 1.0f));
|
||||
_transform._invalidProj = true;
|
||||
}
|
||||
|
||||
|
@ -2474,6 +2536,8 @@ void VKBackend::do_setUniformBuffer(const Batch& batch, size_t paramOffset) {
|
|||
//glBindBufferRange(VK_UNIFORM_BUFFER, slot, object->_buffer, rangeStart, rangeSize);
|
||||
|
||||
_uniform._buffers[slot].buffer = uniformBuffer.get();
|
||||
_uniform._buffers[slot].offset = rangeStart;
|
||||
_uniform._buffers[slot].size = rangeSize;
|
||||
} else {
|
||||
releaseResourceTexture(slot);
|
||||
return;
|
||||
|
|
|
@ -239,6 +239,58 @@ void VKAttachmentTexture::createTexture(VKBackend &backend) {
|
|||
|
||||
}
|
||||
|
||||
VKAttachmentTexture::~VKAttachmentTexture() {
|
||||
auto backend = _backend.lock();
|
||||
auto device = backend->getContext().device->logicalDevice;
|
||||
if (_vkImageView) {
|
||||
vkDestroyImageView(device, _vkImageView, nullptr);
|
||||
}
|
||||
if (_vkSampler) {
|
||||
vkDestroySampler(device, _vkSampler, nullptr);
|
||||
}
|
||||
vmaDestroyImage(vks::Allocation::getAllocator(), _vkImage, _vmaAllocation);
|
||||
}
|
||||
|
||||
VkDescriptorImageInfo VKAttachmentTexture::getDescriptorImageInfo() {
|
||||
if (_vkSampler == VK_NULL_HANDLE) {
|
||||
auto backend = _backend.lock();
|
||||
auto device = backend->getContext().device;
|
||||
// Create sampler
|
||||
VkSamplerCreateInfo samplerCreateInfo = {};
|
||||
samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||
samplerCreateInfo.magFilter = VK_FILTER_LINEAR; // VKTODO
|
||||
samplerCreateInfo.minFilter = VK_FILTER_LINEAR; // VKTODO
|
||||
samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerCreateInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerCreateInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerCreateInfo.mipLodBias = 0.0f;
|
||||
samplerCreateInfo.compareOp = VK_COMPARE_OP_NEVER;
|
||||
samplerCreateInfo.minLod = 0.0f;
|
||||
samplerCreateInfo.maxLod = 0.0f;
|
||||
samplerCreateInfo.maxAnisotropy = 1.0f;
|
||||
VK_CHECK_RESULT(vkCreateSampler(device->logicalDevice, &samplerCreateInfo, nullptr, &_vkSampler));
|
||||
|
||||
// Create image view
|
||||
VkImageViewCreateInfo viewCreateInfo = {};
|
||||
viewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
viewCreateInfo.pNext = nullptr;
|
||||
viewCreateInfo.viewType = getVKTextureType(_gpuObject);
|
||||
viewCreateInfo.format = evalTexelFormatInternal(_gpuObject.getTexelFormat());
|
||||
viewCreateInfo.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
|
||||
viewCreateInfo.subresourceRange.levelCount = 1;
|
||||
viewCreateInfo.image = _vkImage;
|
||||
VK_CHECK_RESULT(vkCreateImageView(device->logicalDevice, &viewCreateInfo, nullptr, &_vkImageView));
|
||||
}
|
||||
|
||||
VkDescriptorImageInfo result {};
|
||||
result.sampler = _vkSampler;
|
||||
result.imageLayout = _vkImageLayout;
|
||||
result.imageView = _vkImageView;
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
void VKStrictResourceTexture::createTexture(VKBackend &backend) {
|
||||
VkImageCreateInfo imageCI = vks::initializers::imageCreateInfo();
|
||||
imageCI.imageType = VK_IMAGE_TYPE_2D;
|
||||
|
@ -250,6 +302,10 @@ void VKStrictResourceTexture::createTexture(VKBackend &backend) {
|
|||
imageCI.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
imageCI.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
imageCI.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
if (_gpuObject.getType() == Texture::TEX_CUBE) {
|
||||
imageCI.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
|
||||
imageCI.arrayLayers = 6;
|
||||
}
|
||||
|
||||
//auto device = _backend.lock()->getContext().device->logicalDevice;
|
||||
|
||||
|
@ -274,23 +330,34 @@ void VKStrictResourceTexture::createTexture(VKBackend &backend) {
|
|||
if (!_gpuObject.isStoredMipFaceAvailable(sourceMip)) {
|
||||
continue;
|
||||
}
|
||||
// VKTODO: iterate through faces?
|
||||
auto dim = _gpuObject.evalMipDimensions(sourceMip);
|
||||
auto mipData = _gpuObject.accessStoredMipFace(sourceMip, 0); // VKTODO: only one face for now
|
||||
auto mipSize = _gpuObject.getStoredMipFaceSize(sourceMip, 0);
|
||||
if (mipData) {
|
||||
TransferData::Mip mip {};
|
||||
mip.offset = _transferData.buffer_size;
|
||||
mip.size = mipSize;
|
||||
mip.data = mipData;
|
||||
mip.width = dim.x;
|
||||
mip.height = dim.y;
|
||||
_transferData.buffer_size += mipSize;
|
||||
_transferData.mips.push_back(mip);
|
||||
// VKTODO auto texelFormat = evalTexelFormatInternal(_gpuObject.getStoredMipFormat());
|
||||
//return copyMipFaceLinesFromTexture(targetMip, face, dim, 0, texelFormat.internalFormat, texelFormat.format, texelFormat.type, mipSize, mipData->readData());
|
||||
} else {
|
||||
qCDebug(gpu_vk_logging) << "Missing mipData level=" << sourceMip << " face=" << 0/*(int)face*/ << " for texture " << _gpuObject.source().c_str();
|
||||
_transferData.mips.emplace_back();
|
||||
//VKTODO: error out if needed
|
||||
size_t face_count = 1;
|
||||
if (_gpuObject.getType() == Texture::TEX_CUBE) {
|
||||
Q_ASSERT(_gpuObject.getNumFaces() == 6);
|
||||
face_count = 6;
|
||||
}else{
|
||||
Q_ASSERT(_gpuObject.getNumFaces() == 1);
|
||||
}
|
||||
for (size_t face = 0; face < face_count; face++) {
|
||||
auto dim = _gpuObject.evalMipDimensions(sourceMip);
|
||||
auto mipData = _gpuObject.accessStoredMipFace(sourceMip, face); // VKTODO: only one face for now
|
||||
auto mipSize = _gpuObject.getStoredMipFaceSize(sourceMip, face);
|
||||
if (mipData) {
|
||||
TransferData::Mip mip{};
|
||||
mip.offset = _transferData.buffer_size;
|
||||
mip.size = mipSize;
|
||||
mip.data = mipData;
|
||||
mip.width = dim.x;
|
||||
mip.height = dim.y;
|
||||
_transferData.buffer_size += mipSize;
|
||||
_transferData.mips.back().push_back(mip);
|
||||
// VKTODO auto texelFormat = evalTexelFormatInternal(_gpuObject.getStoredMipFormat());
|
||||
//return copyMipFaceLinesFromTexture(targetMip, face, dim, 0, texelFormat.internalFormat, texelFormat.format, texelFormat.type, mipSize, mipData->readData());
|
||||
} else {
|
||||
qCDebug(gpu_vk_logging) << "Missing mipData level=" << sourceMip
|
||||
<< " face=" << 0 /*(int)face*/ << " for texture " << _gpuObject.source().c_str();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -337,23 +404,27 @@ void VKStrictResourceTexture::transfer(VKBackend &backend) {
|
|||
uint8_t *data;
|
||||
VK_CHECK_RESULT(vkMapMemory(device->logicalDevice, stagingMemory, 0, memReqs.size, 0, (void **)&data));
|
||||
for (auto &mip : _transferData.mips) {
|
||||
memcpy(data + mip.offset, mip.data->data(), mip.data->size());
|
||||
for (auto &face : mip) {
|
||||
memcpy(data + face.offset, face.data->data(), face.data->size());
|
||||
}
|
||||
}
|
||||
vkUnmapMemory(device->logicalDevice, stagingMemory);
|
||||
|
||||
std::vector<VkBufferImageCopy> bufferCopyRegions;
|
||||
|
||||
for (size_t mipLevel = 0; mipLevel < _transferData.mips.size(); mipLevel++) {
|
||||
VkBufferImageCopy bufferCopyRegion = {};
|
||||
bufferCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
bufferCopyRegion.imageSubresource.mipLevel = mipLevel;
|
||||
bufferCopyRegion.imageSubresource.baseArrayLayer = 0;
|
||||
bufferCopyRegion.imageSubresource.layerCount = 1;
|
||||
bufferCopyRegion.imageExtent.width = _transferData.mips[mipLevel].width;
|
||||
bufferCopyRegion.imageExtent.height = _transferData.mips[mipLevel].height;
|
||||
bufferCopyRegion.imageExtent.depth = 1;
|
||||
bufferCopyRegion.bufferOffset = _transferData.mips[mipLevel].offset;
|
||||
bufferCopyRegions.push_back(bufferCopyRegion);
|
||||
for (size_t face = 0; face < _transferData.mips[mipLevel].size(); face++) {
|
||||
VkBufferImageCopy bufferCopyRegion = {};
|
||||
bufferCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
bufferCopyRegion.imageSubresource.mipLevel = mipLevel;
|
||||
bufferCopyRegion.imageSubresource.baseArrayLayer = face;
|
||||
bufferCopyRegion.imageSubresource.layerCount = 1;
|
||||
bufferCopyRegion.imageExtent.width = _transferData.mips[mipLevel][face].width;
|
||||
bufferCopyRegion.imageExtent.height = _transferData.mips[mipLevel][face].height;
|
||||
bufferCopyRegion.imageExtent.depth = 1;
|
||||
bufferCopyRegion.bufferOffset = _transferData.mips[mipLevel][face].offset;
|
||||
bufferCopyRegions.push_back(bufferCopyRegion);
|
||||
}
|
||||
}
|
||||
|
||||
// Create optimal tiled target image
|
||||
|
@ -389,7 +460,11 @@ void VKStrictResourceTexture::transfer(VKBackend &backend) {
|
|||
subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
subresourceRange.baseMipLevel = 0;
|
||||
subresourceRange.levelCount = _transferData.mips.size();
|
||||
subresourceRange.layerCount = 1;
|
||||
if (_gpuObject.getType() == Texture::TEX_CUBE) {
|
||||
subresourceRange.layerCount = 6;
|
||||
}else{
|
||||
subresourceRange.layerCount = 1;
|
||||
}
|
||||
|
||||
// Image barrier for optimal image (target)
|
||||
// Optimal image will be used as destination for the copy
|
||||
|
@ -448,14 +523,30 @@ void VKStrictResourceTexture::postTransfer(VKBackend &backend) {
|
|||
VkImageViewCreateInfo viewCreateInfo = {};
|
||||
viewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
viewCreateInfo.pNext = nullptr;
|
||||
viewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
viewCreateInfo.viewType = getVKTextureType(_gpuObject);
|
||||
viewCreateInfo.format = evalTexelFormatInternal(_gpuObject.getTexelFormat());
|
||||
viewCreateInfo.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
|
||||
viewCreateInfo.subresourceRange.levelCount = 1;
|
||||
if (_gpuObject.getType() == Texture::TEX_CUBE) {
|
||||
viewCreateInfo.subresourceRange.layerCount = 6;
|
||||
} else {
|
||||
viewCreateInfo.subresourceRange.layerCount = 1;
|
||||
}
|
||||
viewCreateInfo.image = _vkImage;
|
||||
VK_CHECK_RESULT(vkCreateImageView(device->logicalDevice, &viewCreateInfo, nullptr, &_vkImageView));
|
||||
};
|
||||
|
||||
VKStrictResourceTexture::~VKStrictResourceTexture() {
|
||||
auto backend = _backend.lock();
|
||||
auto device = backend->getContext().device->logicalDevice;
|
||||
vkDestroyImageView(device, _vkImageView, nullptr);
|
||||
if (_vkSampler)
|
||||
{
|
||||
vkDestroySampler(device, _vkSampler, nullptr);
|
||||
}
|
||||
vmaDestroyImage(vks::Allocation::getAllocator(), _vkImage, _vmaAllocation);
|
||||
}
|
||||
|
||||
/*Size VKTexture::copyMipFaceFromTexture(uint16_t sourceMip, uint16_t targetMip, uint8_t face) const {
|
||||
if (!_gpuObject.isStoredMipFaceAvailable(sourceMip)) {
|
||||
return 0;
|
||||
|
|
|
@ -216,7 +216,7 @@ protected:
|
|||
uint32_t height;
|
||||
std::shared_ptr<const storage::Storage> data;
|
||||
};
|
||||
std::vector<Mip> mips;
|
||||
std::vector<std::vector<Mip>> mips;
|
||||
};
|
||||
TransferData _transferData{};
|
||||
virtual void transfer(VKBackend &backend) = 0;
|
||||
|
@ -266,16 +266,16 @@ protected:
|
|||
VKFixedAllocationTexture(backend, texture, false) {
|
||||
VKAttachmentTexture::createTexture(*backend.lock());
|
||||
};
|
||||
virtual ~VKAttachmentTexture() {}; // VKTODO: delete image and image view, release memory
|
||||
virtual ~VKAttachmentTexture(); // VKTODO: delete image and image view, release memory
|
||||
void createTexture(VKBackend &backend) override;
|
||||
void transfer(VKBackend &backend) override {}; // VKTODO
|
||||
void postTransfer(VKBackend &backend) override {}; // VKTODO
|
||||
|
||||
VkDescriptorImageInfo getDescriptorImageInfo() override {
|
||||
Q_ASSERT(false);
|
||||
return {};
|
||||
}; // VKTODO
|
||||
VkDescriptorImageInfo getDescriptorImageInfo() override; // VKTODO
|
||||
|
||||
VkImageView _vkImageView { VK_NULL_HANDLE };
|
||||
VkImageLayout _vkImageLayout {}; // VKTODO
|
||||
VkSampler _vkSampler { VK_NULL_HANDLE };
|
||||
//VkImage _vkImage { VK_NULL_HANDLE };
|
||||
//VkDeviceMemory _vkDeviceMemory{ VK_NULL_HANDLE };
|
||||
};
|
||||
|
@ -293,7 +293,7 @@ protected:
|
|||
VKStrictResourceTexture::transfer(vkBackend);
|
||||
VKStrictResourceTexture::postTransfer(vkBackend);
|
||||
};
|
||||
~VKStrictResourceTexture() override {}; // VKTODO: delete image and image view, release memory
|
||||
~VKStrictResourceTexture() override; // VKTODO: delete image and image view, release memory
|
||||
void createTexture(VKBackend &backend) override;
|
||||
void transfer(VKBackend &backend) override;
|
||||
void postTransfer(VKBackend &backend) override;
|
||||
|
|
|
@ -112,11 +112,11 @@ namespace vks {
|
|||
VkPipelineDepthStencilStateCreateInfo{} {
|
||||
sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
||||
if (depthEnable) {
|
||||
//depthTestEnable = VK_TRUE; //VKTODO
|
||||
depthTestEnable = VK_FALSE;
|
||||
depthTestEnable = VK_TRUE; //VKTODO
|
||||
//depthTestEnable = VK_FALSE;
|
||||
depthWriteEnable = VK_TRUE;
|
||||
//depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; //VKTODO
|
||||
depthCompareOp = VK_COMPARE_OP_ALWAYS;
|
||||
depthCompareOp = VK_COMPARE_OP_GREATER_OR_EQUAL; //VKTODO
|
||||
//depthCompareOp = VK_COMPARE_OP_ALWAYS;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -465,7 +465,7 @@ namespace vks
|
|||
pipelineDepthStencilStateCreateInfo.depthTestEnable = depthTestEnable;
|
||||
pipelineDepthStencilStateCreateInfo.depthWriteEnable = depthWriteEnable;
|
||||
pipelineDepthStencilStateCreateInfo.depthCompareOp = depthCompareOp;
|
||||
pipelineDepthStencilStateCreateInfo.back.compareOp = VK_COMPARE_OP_ALWAYS;
|
||||
//pipelineDepthStencilStateCreateInfo.back.compareOp = VK_COMPARE_OP_ALWAYS;
|
||||
return pipelineDepthStencilStateCreateInfo;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue