nvk: Reserve a sampler for TXF on Kepler
The SPIR-V spec says texelFetch and friends don't take a sampler. However, on Kepler and earlier hardware, the sampler is read even for tld. In particular, the hardware reads the sRGB conversion bit in the sampler and this can be in an inconsistent state if we haven't initialized samplers properly. On Kepler, we should just reserve a sampler at device creation time and always use that for tld. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35190>
This commit is contained in:
committed by
Marge Bot
parent
bfdc95b109
commit
8ffe0098be
@@ -8,6 +8,7 @@
|
||||
#include "nvk_entrypoints.h"
|
||||
#include "nvk_instance.h"
|
||||
#include "nvk_physical_device.h"
|
||||
#include "nvk_sampler.h"
|
||||
#include "nvk_shader.h"
|
||||
#include "nvkmd/nvkmd.h"
|
||||
|
||||
@@ -200,6 +201,23 @@ nvk_CreateDevice(VkPhysicalDevice physicalDevice,
|
||||
if (result != VK_SUCCESS)
|
||||
goto fail_images;
|
||||
|
||||
/* On Kepler and earlier, TXF takes a sampler but SPIR-V defines it as not
|
||||
* taking one so we need to reserve one at device create time. If we do so
|
||||
* now then it will always have sampler index 0 so we can rely on that in
|
||||
* the compiler lowering code (similar to null descriptors).
|
||||
*/
|
||||
if (pdev->info.cls_eng3d < MAXWELL_A) {
|
||||
uint32_t txf_sampler[8] = {};
|
||||
nvk_fill_txf_sampler_header(pdev, txf_sampler);
|
||||
|
||||
ASSERTED uint32_t txf_sampler_index;
|
||||
result = nvk_descriptor_table_add(dev, &dev->samplers,
|
||||
txf_sampler, sizeof(txf_sampler),
|
||||
&txf_sampler_index);
|
||||
assert(result == VK_SUCCESS);
|
||||
assert(txf_sampler_index == 0);
|
||||
}
|
||||
|
||||
if (dev->vk.enabled_features.descriptorBuffer ||
|
||||
nvk_use_edb_buffer_views(pdev)) {
|
||||
result = nvk_edb_bview_cache_init(dev, &dev->edb_bview_cache);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "nir_builder.h"
|
||||
#include "nir_deref.h"
|
||||
|
||||
#include "clb097.h"
|
||||
#include "clc397.h"
|
||||
#include "clc597.h"
|
||||
|
||||
@@ -1301,7 +1302,21 @@ lower_tex(nir_builder *b, nir_tex_instr *tex,
|
||||
load_resource_deref_desc(b, 1, 32, texture, plane_offset_B, ctx);
|
||||
|
||||
nir_def *combined_handle;
|
||||
if (texture == sampler || !nir_tex_instr_need_sampler(tex)) {
|
||||
|
||||
if (!nir_tex_instr_need_sampler(tex)) {
|
||||
combined_handle = texture_desc;
|
||||
|
||||
/* On Kepler and earlier, TXF takes a sampler but SPIR-V defines it as
|
||||
* not taking one so we can't trust the sampler from the client's image
|
||||
* descriptor. Instead, mask off the top bits so we get a zero sampler
|
||||
* index which we've conveniently reserved at device cration time for a
|
||||
* special TXF sampler.
|
||||
*/
|
||||
if (ctx->dev_info->cls_eng3d < MAXWELL_A) {
|
||||
combined_handle = nir_iand_imm(b, combined_handle,
|
||||
NVK_IMAGE_DESCRIPTOR_IMAGE_INDEX_MASK);
|
||||
}
|
||||
} else if (texture == sampler) {
|
||||
combined_handle = texture_desc;
|
||||
} else {
|
||||
combined_handle = nir_iand_imm(b, texture_desc,
|
||||
|
||||
@@ -282,6 +282,30 @@ nvk_sampler_fill_header(const struct nvk_physical_device *pdev,
|
||||
SAMP_SET_U(samp, NV9097, 7, BORDER_COLOR_A, bc.uint32[3]);
|
||||
}
|
||||
|
||||
void
|
||||
nvk_fill_txf_sampler_header(const struct nvk_physical_device *pdev,
|
||||
uint32_t *samp)
|
||||
{
|
||||
const VkSamplerCreateInfo sampler_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
||||
.magFilter = VK_FILTER_NEAREST,
|
||||
.minFilter = VK_FILTER_NEAREST,
|
||||
.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST,
|
||||
.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
|
||||
.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
|
||||
.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
|
||||
.borderColor = VK_BORDER_COLOR_INT_TRANSPARENT_BLACK,
|
||||
.minLod = 0.0,
|
||||
.maxLod = 16.0,
|
||||
.unnormalizedCoordinates = true,
|
||||
};
|
||||
|
||||
struct vk_sampler sampler;
|
||||
vk_sampler_init(&sampler_info, &sampler);
|
||||
|
||||
nvk_sampler_fill_header(pdev, &sampler_info, &sampler, samp);
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
nvk_CreateSampler(VkDevice device,
|
||||
const VkSamplerCreateInfo *pCreateInfo,
|
||||
|
||||
@@ -32,10 +32,8 @@ struct nvk_sampler_capture {
|
||||
} planes[NVK_MAX_SAMPLER_PLANES];
|
||||
};
|
||||
|
||||
static void
|
||||
nvk_sampler_fill_header(const struct nvk_physical_device *pdev,
|
||||
const struct VkSamplerCreateInfo *info,
|
||||
const struct vk_sampler *vk_sampler,
|
||||
uint32_t *samp);
|
||||
void
|
||||
nvk_fill_txf_sampler_header(const struct nvk_physical_device *pdev,
|
||||
uint32_t *samp);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user