hk: fix null FS corner cases
this fixes null FS + cull distance/API sample mask, which require a prolog. fixes upcoming CTS. Backport-to: 25.1 Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34585> (cherry picked from commit 3ab8ce8579c967e1d8fb024de298a958511d9ffd)
This commit is contained in:

committed by
Eric Engestrom

parent
5c048f7860
commit
3cc215b1cc
@@ -1424,7 +1424,7 @@
|
||||
"description": "hk: fix null FS corner cases",
|
||||
"nominated": true,
|
||||
"nomination_type": 4,
|
||||
"resolution": 0,
|
||||
"resolution": 1,
|
||||
"main_sha": null,
|
||||
"because_sha": null,
|
||||
"notes": null
|
||||
|
@@ -1636,8 +1636,18 @@ hk_cmd_bind_graphics_shader(struct hk_cmd_buffer *cmd,
|
||||
const gl_shader_stage stage,
|
||||
struct hk_api_shader *shader)
|
||||
{
|
||||
struct hk_device *dev = hk_cmd_buffer_device(cmd);
|
||||
struct vk_dynamic_graphics_state *dyn = &cmd->vk.dynamic_graphics_state;
|
||||
|
||||
/* Null fragment shaders are annoying to handle, because we may still need an
|
||||
* actual fragment shader to attach a prolog to. Rather than adding special
|
||||
* cases, we just bind an empty fragment shader instead of NULL to make
|
||||
* everything work correctly.
|
||||
*/
|
||||
if (stage == MESA_SHADER_FRAGMENT && shader == NULL) {
|
||||
shader = dev->null_fs;
|
||||
}
|
||||
|
||||
assert(stage < ARRAY_SIZE(cmd->state.gfx.shaders));
|
||||
if (cmd->state.gfx.shaders[stage] == shader)
|
||||
return;
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#include "asahi/lib/agx_bo.h"
|
||||
#include "asahi/lib/agx_device.h"
|
||||
#include "asahi/libagx/geometry.h"
|
||||
#include "compiler/nir/nir_builder.h"
|
||||
#include "util/hash_table.h"
|
||||
#include "util/ralloc.h"
|
||||
#include "util/simple_mtx.h"
|
||||
@@ -466,6 +467,23 @@ hk_CreateDevice(VkPhysicalDevice physicalDevice,
|
||||
if (result != VK_SUCCESS)
|
||||
goto fail_mem_cache;
|
||||
|
||||
/* Precompile an empty fragment shader that can be used to handle API-level
|
||||
* null fragment shaders. We do this at device-time to make binds cheap.
|
||||
* Regardless, compiling this shader should be fast.
|
||||
*/
|
||||
nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT,
|
||||
&agx_nir_options, "empty FS");
|
||||
struct vk_shader_compile_info info = {
|
||||
.nir = b.shader,
|
||||
.robustness = &vk_robustness_disabled,
|
||||
.stage = MESA_SHADER_FRAGMENT,
|
||||
};
|
||||
hk_compile_shader(dev, &info, NULL, pAllocator, &dev->null_fs);
|
||||
if (!dev->null_fs) {
|
||||
result = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
goto fail_meta;
|
||||
}
|
||||
|
||||
*pDevice = hk_device_to_handle(dev);
|
||||
|
||||
simple_mtx_init(&dev->scratch.lock, mtx_plain);
|
||||
@@ -479,6 +497,8 @@ hk_CreateDevice(VkPhysicalDevice physicalDevice,
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
||||
fail_meta:
|
||||
hk_device_finish_meta(dev);
|
||||
fail_mem_cache:
|
||||
vk_pipeline_cache_destroy(dev->mem_cache, NULL);
|
||||
fail_queue:
|
||||
@@ -534,6 +554,10 @@ hk_DestroyDevice(VkDevice _device, const VkAllocationCallbacks *pAllocator)
|
||||
agx_scratch_fini(&dev->scratch.cs);
|
||||
simple_mtx_destroy(&dev->scratch.lock);
|
||||
|
||||
if (dev->null_fs) {
|
||||
hk_api_shader_destroy(&dev->vk, &dev->null_fs->vk, pAllocator);
|
||||
}
|
||||
|
||||
hk_destroy_sampler_heap(dev, &dev->samplers);
|
||||
hk_descriptor_table_finish(dev, &dev->images);
|
||||
hk_descriptor_table_finish(dev, &dev->occlusion_queries);
|
||||
|
@@ -98,7 +98,7 @@ struct hk_device {
|
||||
|
||||
struct hk_internal_shaders prolog_epilog;
|
||||
struct hk_internal_shaders kernels;
|
||||
struct hk_api_shader *write_shader;
|
||||
struct hk_api_shader *null_fs;
|
||||
|
||||
/* Indirected for common secondary emulation */
|
||||
struct vk_device_dispatch_table cmd_dispatch;
|
||||
|
Reference in New Issue
Block a user