mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-11 01:24:12 +01:00
[dxvk] Initialize dummy resources to zero
Read access to unbound images and buffers usually yields a result vector that contains zeroes in all components.
This commit is contained in:
parent
d4a0581f8f
commit
c66492a90f
@ -196,7 +196,12 @@ namespace dxvk {
|
||||
|
||||
if (m_vki->vkCreateDevice(m_handle, &info, nullptr, &device) != VK_SUCCESS)
|
||||
throw DxvkError("DxvkAdapter: Failed to create device");
|
||||
return new DxvkDevice(this, new vk::DeviceFn(m_vki->instance(), device), extensions, enabledFeatures);
|
||||
|
||||
Rc<DxvkDevice> result = new DxvkDevice(this,
|
||||
new vk::DeviceFn(m_vki->instance(), device),
|
||||
extensions, enabledFeatures);
|
||||
result->initResources();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -304,6 +304,17 @@ namespace dxvk {
|
||||
m_vkd->vkCmdEndRenderPass(m_buffer);
|
||||
}
|
||||
|
||||
|
||||
void cmdFillBuffer(
|
||||
VkBuffer dstBuffer,
|
||||
VkDeviceSize dstOffset,
|
||||
VkDeviceSize size,
|
||||
uint32_t data) {
|
||||
m_vkd->vkCmdFillBuffer(m_buffer,
|
||||
dstBuffer, dstOffset, size, data);
|
||||
}
|
||||
|
||||
|
||||
void cmdPipelineBarrier(
|
||||
VkPipelineStageFlags srcStageMask,
|
||||
VkPipelineStageFlags dstStageMask,
|
||||
|
@ -175,6 +175,32 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::clearBuffer(
|
||||
const Rc<DxvkBuffer>& buffer,
|
||||
VkDeviceSize offset,
|
||||
VkDeviceSize length,
|
||||
uint32_t value) {
|
||||
this->renderPassEnd();
|
||||
|
||||
auto slice = buffer->subSlice(offset, length);
|
||||
|
||||
m_cmd->cmdFillBuffer(
|
||||
slice.handle(),
|
||||
slice.offset(),
|
||||
slice.length(),
|
||||
value);
|
||||
|
||||
m_barriers.accessBuffer(slice,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
buffer->info().stages,
|
||||
buffer->info().access);
|
||||
m_barriers.recordCommands(m_cmd);
|
||||
|
||||
m_cmd->trackResource(slice.resource());
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::clearColorImage(
|
||||
const Rc<DxvkImage>& image,
|
||||
const VkClearColorValue& value,
|
||||
|
@ -135,6 +135,23 @@ namespace dxvk {
|
||||
const DxvkBufferSlice& buffer,
|
||||
uint32_t stride);
|
||||
|
||||
/**
|
||||
* \brief Clears a buffer with a fixed value
|
||||
*
|
||||
* Note that both \c offset and \c length must
|
||||
* be multiples of four, and that \c value is
|
||||
* consumed as a four-byte word.
|
||||
* \param [in] buffer The buffer to clear
|
||||
* \param [in] offset Offset of the range to clear
|
||||
* \param [in] length Bumber of bytes to clear
|
||||
* \param [in] value Clear value
|
||||
*/
|
||||
void clearBuffer(
|
||||
const Rc<DxvkBuffer>& buffer,
|
||||
VkDeviceSize offset,
|
||||
VkDeviceSize length,
|
||||
uint32_t value);
|
||||
|
||||
/**
|
||||
* \brief Clears subresources of a color image
|
||||
*
|
||||
|
@ -192,6 +192,11 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxvkDevice::initResources() {
|
||||
m_unboundResources.clearResources(this);
|
||||
}
|
||||
|
||||
|
||||
VkResult DxvkDevice::presentSwapImage(
|
||||
const VkPresentInfoKHR& presentInfo) {
|
||||
m_statCounters.increment(DxvkStat::DevQueuePresents, 1);
|
||||
|
@ -35,6 +35,7 @@ namespace dxvk {
|
||||
* contexts. Multiple contexts can be created for a device.
|
||||
*/
|
||||
class DxvkDevice : public RcObject {
|
||||
friend class DxvkContext;
|
||||
friend class DxvkSubmissionQueue;
|
||||
|
||||
constexpr static VkDeviceSize DefaultStagingBufferSize = 4 * 1024 * 1024;
|
||||
@ -276,46 +277,13 @@ namespace dxvk {
|
||||
const DxvkSwapchainProperties& properties);
|
||||
|
||||
/**
|
||||
* \brief Dummy buffer handle
|
||||
* \returns Use for unbound vertex buffers.
|
||||
*/
|
||||
VkBuffer dummyBufferHandle() const {
|
||||
return m_unboundResources.bufferHandle();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Dummy buffer descriptor
|
||||
* \returns Descriptor that points to a dummy buffer
|
||||
*/
|
||||
VkDescriptorBufferInfo dummyBufferDescriptor() const {
|
||||
return m_unboundResources.bufferDescriptor();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Dummy buffer view descriptor
|
||||
* \returns Dummy buffer view handle
|
||||
*/
|
||||
VkBufferView dummyBufferViewDescriptor() const {
|
||||
return m_unboundResources.bufferViewDescriptor();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Dummy sampler descriptor
|
||||
* \returns Descriptor that points to a dummy sampler
|
||||
*/
|
||||
VkDescriptorImageInfo dummySamplerDescriptor() const {
|
||||
return m_unboundResources.samplerDescriptor();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Dummy image view descriptor
|
||||
* \brief Initializes dummy resources
|
||||
*
|
||||
* \param [in] type Required view type
|
||||
* \returns Descriptor that points to a dummy image
|
||||
* Should be called after creating the device in
|
||||
* case the device initialization was successful
|
||||
* and the device is usable.
|
||||
*/
|
||||
VkDescriptorImageInfo dummyImageViewDescriptor(VkImageViewType type) const {
|
||||
return m_unboundResources.imageViewDescriptor(type);
|
||||
}
|
||||
void initResources();
|
||||
|
||||
/**
|
||||
* \brief Presents a swap chain image
|
||||
@ -379,7 +347,6 @@ namespace dxvk {
|
||||
VkQueue m_graphicsQueue = VK_NULL_HANDLE;
|
||||
VkQueue m_presentQueue = VK_NULL_HANDLE;
|
||||
|
||||
// TODO fine-tune buffer sizes
|
||||
DxvkRecycler<DxvkCommandList, 16> m_recycledCommandLists;
|
||||
DxvkRecycler<DxvkStagingBuffer, 4> m_recycledStagingBuffers;
|
||||
|
||||
@ -390,6 +357,48 @@ namespace dxvk {
|
||||
void recycleCommandList(
|
||||
const Rc<DxvkCommandList>& cmdList);
|
||||
|
||||
/**
|
||||
* \brief Dummy buffer handle
|
||||
* \returns Use for unbound vertex buffers.
|
||||
*/
|
||||
VkBuffer dummyBufferHandle() const {
|
||||
return m_unboundResources.bufferHandle();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Dummy buffer descriptor
|
||||
* \returns Descriptor that points to a dummy buffer
|
||||
*/
|
||||
VkDescriptorBufferInfo dummyBufferDescriptor() const {
|
||||
return m_unboundResources.bufferDescriptor();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Dummy buffer view descriptor
|
||||
* \returns Dummy buffer view handle
|
||||
*/
|
||||
VkBufferView dummyBufferViewDescriptor() const {
|
||||
return m_unboundResources.bufferViewDescriptor();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Dummy sampler descriptor
|
||||
* \returns Descriptor that points to a dummy sampler
|
||||
*/
|
||||
VkDescriptorImageInfo dummySamplerDescriptor() const {
|
||||
return m_unboundResources.samplerDescriptor();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Dummy image view descriptor
|
||||
*
|
||||
* \param [in] type Required view type
|
||||
* \returns Descriptor that points to a dummy image
|
||||
*/
|
||||
VkDescriptorImageInfo dummyImageViewDescriptor(VkImageViewType type) const {
|
||||
return m_unboundResources.imageViewDescriptor(type);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -25,6 +25,21 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxvkUnboundResources::clearResources(DxvkDevice* dev) {
|
||||
const Rc<DxvkContext> ctx = dev->createContext();
|
||||
ctx->beginRecording(dev->createCommandList());
|
||||
|
||||
this->clearBuffer(ctx, m_buffer);
|
||||
this->clearImage(ctx, m_image1D);
|
||||
this->clearImage(ctx, m_image2D);
|
||||
this->clearImage(ctx, m_image3D);
|
||||
|
||||
dev->submitCommandList(
|
||||
ctx->endRecording(),
|
||||
nullptr, nullptr);
|
||||
}
|
||||
|
||||
|
||||
Rc<DxvkSampler> DxvkUnboundResources::createSampler(DxvkDevice* dev) {
|
||||
DxvkSamplerCreateInfo info;
|
||||
info.minFilter = VK_FILTER_LINEAR;
|
||||
@ -50,11 +65,13 @@ namespace dxvk {
|
||||
Rc<DxvkBuffer> DxvkUnboundResources::createBuffer(DxvkDevice* dev) {
|
||||
DxvkBufferCreateInfo info;
|
||||
info.size = 4;
|
||||
info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
|
||||
info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT
|
||||
| VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
|
||||
| VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
||||
| VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT
|
||||
| VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
|
||||
info.stages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
|
||||
info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT
|
||||
| VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
|
||||
| VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
|
||||
| VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
|
||||
| VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
|
||||
@ -93,9 +110,11 @@ namespace dxvk {
|
||||
info.extent = { 1, 1, 1 };
|
||||
info.numLayers = layers;
|
||||
info.mipLevels = 1;
|
||||
info.usage = VK_IMAGE_USAGE_SAMPLED_BIT
|
||||
info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT
|
||||
| VK_IMAGE_USAGE_SAMPLED_BIT
|
||||
| VK_IMAGE_USAGE_STORAGE_BIT;
|
||||
info.stages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
|
||||
info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT
|
||||
| VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
|
||||
| VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
|
||||
| VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
|
||||
| VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
|
||||
@ -147,4 +166,23 @@ namespace dxvk {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DxvkUnboundResources::clearBuffer(
|
||||
const Rc<DxvkContext>& ctx,
|
||||
const Rc<DxvkBuffer>& buffer) {
|
||||
ctx->clearBuffer(buffer, 0, buffer->info().size, 0);
|
||||
}
|
||||
|
||||
|
||||
void DxvkUnboundResources::clearImage(
|
||||
const Rc<DxvkContext>& ctx,
|
||||
const Rc<DxvkImage>& image) {
|
||||
ctx->clearColorImage(image,
|
||||
VkClearColorValue { },
|
||||
VkImageSubresourceRange {
|
||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
0, image->info().mipLevels,
|
||||
0, image->info().numLayers });
|
||||
}
|
||||
|
||||
}
|
@ -35,8 +35,9 @@ namespace dxvk {
|
||||
/**
|
||||
* \brief Dummy buffer descriptor
|
||||
*
|
||||
* Points to a small buffer with undefined
|
||||
* values. Do not access this buffer.
|
||||
* Points to a small buffer filled with zeroes.
|
||||
* Do not write to this buffer, and do not use
|
||||
* it if out-of-bounds read access is possible.
|
||||
* \returns Dummy buffer descriptor
|
||||
*/
|
||||
VkDescriptorBufferInfo bufferDescriptor() const {
|
||||
@ -95,6 +96,14 @@ namespace dxvk {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clears the resources
|
||||
*
|
||||
* Initializes all images and buffers to zero.
|
||||
* \param [in] dev The DXVK device handle
|
||||
*/
|
||||
void clearResources(DxvkDevice* dev);
|
||||
|
||||
private:
|
||||
|
||||
Rc<DxvkSampler> m_sampler;
|
||||
@ -136,6 +145,14 @@ namespace dxvk {
|
||||
const DxvkImageView* getImageView(
|
||||
VkImageViewType type) const;
|
||||
|
||||
void clearBuffer(
|
||||
const Rc<DxvkContext>& ctx,
|
||||
const Rc<DxvkBuffer>& buffer);
|
||||
|
||||
void clearImage(
|
||||
const Rc<DxvkContext>& ctx,
|
||||
const Rc<DxvkImage>& image);
|
||||
|
||||
};
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user