radv: add fs_key meta format support to resolve passes.
authorDave Airlie <airlied@redhat.com>
Tue, 23 Jan 2018 05:48:08 +0000 (15:48 +1000)
committerDave Airlie <airlied@redhat.com>
Tue, 23 Jan 2018 22:50:51 +0000 (08:50 +1000)
Some of the hw resolve passes need the SPI color format setup
correctly.

This fixes lots of 16-bit and 32-bit format tests in
dEQP-VK.renderpass.suballocation.multisample*

Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Fixes: f4e499ec7914 "radv: add initial non-conformant radv vulkan driver"
Signed-off-by: Dave Airlie <airlied@redhat.com>
src/amd/vulkan/radv_meta_resolve.c
src/amd/vulkan/radv_private.h

index 49326fe9d10693005a01b7e4909ddce14ca63d64..855bf98203967e7d77272c1028204a7b317a91df 100644 (file)
@@ -50,7 +50,7 @@ build_nir_fs(void)
 }
 
 static VkResult
-create_pass(struct radv_device *device)
+create_pass(struct radv_device *device, VkFormat vk_format, VkRenderPass *pass)
 {
        VkResult result;
        VkDevice device_h = radv_device_to_handle(device);
@@ -59,7 +59,7 @@ create_pass(struct radv_device *device)
        int i;
 
        for (i = 0; i < 2; i++) {
-               attachments[i].format = VK_FORMAT_UNDEFINED;
+               attachments[i].format = vk_format;
                attachments[i].samples = 1;
                attachments[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
                attachments[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
@@ -99,14 +99,16 @@ create_pass(struct radv_device *device)
                                                                .dependencyCount = 0,
                                                                         },
                                       alloc,
-                                      &device->meta_state.resolve.pass);
+                                      pass);
 
        return result;
 }
 
 static VkResult
 create_pipeline(struct radv_device *device,
-                VkShaderModule vs_module_h)
+                VkShaderModule vs_module_h,
+                VkPipeline *pipeline,
+                VkRenderPass pass)
 {
        VkResult result;
        VkDevice device_h = radv_device_to_handle(device);
@@ -129,12 +131,14 @@ create_pipeline(struct radv_device *device,
                .pPushConstantRanges = NULL,
        };
 
-       result = radv_CreatePipelineLayout(radv_device_to_handle(device),
-                                          &pl_create_info,
-                                          &device->meta_state.alloc,
-                                          &device->meta_state.resolve.p_layout);
-       if (result != VK_SUCCESS)
-               goto cleanup;
+       if (!device->meta_state.resolve.p_layout) {
+               result = radv_CreatePipelineLayout(radv_device_to_handle(device),
+                                                  &pl_create_info,
+                                                  &device->meta_state.alloc,
+                                                  &device->meta_state.resolve.p_layout);
+               if (result != VK_SUCCESS)
+                       goto cleanup;
+       }
 
        result = radv_graphics_pipeline_create(device_h,
                                               radv_pipeline_cache_to_handle(&device->meta_state.cache),
@@ -212,15 +216,14 @@ create_pipeline(struct radv_device *device,
                                                        },
                                                },
                                                .layout = device->meta_state.resolve.p_layout,
-                                                                                                                                      .renderPass = device->meta_state.resolve.pass,
+                                               .renderPass = pass,
                                                                                                                                       .subpass = 0,
                                                                                                                                       },
                                               &(struct radv_graphics_pipeline_create_info) {
                                                       .use_rectlist = true,
                                                       .custom_blend_mode = V_028808_CB_RESOLVE,
                                                               },
-                                              &device->meta_state.alloc,
-                                              &device->meta_state.resolve.pipeline);
+                                              &device->meta_state.alloc, pipeline);
        if (result != VK_SUCCESS)
                goto cleanup;
 
@@ -236,19 +239,37 @@ radv_device_finish_meta_resolve_state(struct radv_device *device)
 {
        struct radv_meta_state *state = &device->meta_state;
 
-       radv_DestroyRenderPass(radv_device_to_handle(device),
-                              state->resolve.pass, &state->alloc);
+       for (uint32_t j = 0; j < NUM_META_FS_KEYS; j++) {
+               radv_DestroyRenderPass(radv_device_to_handle(device),
+                                      state->resolve.pass[j], &state->alloc);
+               radv_DestroyPipeline(radv_device_to_handle(device),
+                                    state->resolve.pipeline[j], &state->alloc);
+       }
        radv_DestroyPipelineLayout(radv_device_to_handle(device),
                                   state->resolve.p_layout, &state->alloc);
-       radv_DestroyPipeline(radv_device_to_handle(device),
-                            state->resolve.pipeline, &state->alloc);
+
 }
 
+static VkFormat pipeline_formats[] = {
+       VK_FORMAT_R8G8B8A8_UNORM,
+       VK_FORMAT_R8G8B8A8_UINT,
+       VK_FORMAT_R8G8B8A8_SINT,
+       VK_FORMAT_A2R10G10B10_UINT_PACK32,
+       VK_FORMAT_A2R10G10B10_SINT_PACK32,
+       VK_FORMAT_R16G16B16A16_UNORM,
+       VK_FORMAT_R16G16B16A16_SNORM,
+       VK_FORMAT_R16G16B16A16_UINT,
+       VK_FORMAT_R16G16B16A16_SINT,
+       VK_FORMAT_R32_SFLOAT,
+       VK_FORMAT_R32G32_SFLOAT,
+       VK_FORMAT_R32G32B32A32_SFLOAT
+};
+
 VkResult
 radv_device_init_meta_resolve_state(struct radv_device *device)
 {
        VkResult res = VK_SUCCESS;
-
+       struct radv_meta_state *state = &device->meta_state;
        struct radv_shader_module vs_module = { .nir = radv_meta_build_nir_vs_generate_vertices() };
        if (!vs_module.nir) {
                /* XXX: Need more accurate error */
@@ -256,14 +277,19 @@ radv_device_init_meta_resolve_state(struct radv_device *device)
                goto fail;
        }
 
-       res = create_pass(device);
-       if (res != VK_SUCCESS)
-               goto fail;
-
-       VkShaderModule vs_module_h = radv_shader_module_to_handle(&vs_module);
-       res = create_pipeline(device, vs_module_h);
-       if (res != VK_SUCCESS)
-               goto fail;
+       for (uint32_t i = 0; i < ARRAY_SIZE(pipeline_formats); ++i) {
+               VkFormat format = pipeline_formats[i];
+               unsigned fs_key = radv_format_meta_fs_key(format);
+               res = create_pass(device, format, &state->resolve.pass[fs_key]);
+               if (res != VK_SUCCESS)
+                       goto fail;
+
+               VkShaderModule vs_module_h = radv_shader_module_to_handle(&vs_module);
+               res = create_pipeline(device, vs_module_h,
+                                     &state->resolve.pipeline[fs_key], state->resolve.pass[fs_key]);
+               if (res != VK_SUCCESS)
+                       goto fail;
+       }
 
        goto cleanup;
 
@@ -278,16 +304,18 @@ cleanup:
 
 static void
 emit_resolve(struct radv_cmd_buffer *cmd_buffer,
+            VkFormat vk_format,
              const VkOffset2D *dest_offset,
              const VkExtent2D *resolve_extent)
 {
        struct radv_device *device = cmd_buffer->device;
        VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer);
+       unsigned fs_key = radv_format_meta_fs_key(vk_format);
 
        cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_FLUSH_AND_INV_CB;
 
        radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
-                            device->meta_state.resolve.pipeline);
+                            device->meta_state.resolve.pipeline[fs_key]);
 
        radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &(VkViewport) {
                .x = dest_offset->x,
@@ -413,6 +441,7 @@ void radv_CmdResolveImage(
        if (dest_image->surface.dcc_size) {
                radv_initialize_dcc(cmd_buffer, dest_image, 0xffffffff);
        }
+       unsigned fs_key = radv_format_meta_fs_key(dest_image->vk_format);
        for (uint32_t r = 0; r < region_count; ++r) {
                const VkImageResolve *region = &regions[r];
 
@@ -512,7 +541,7 @@ void radv_CmdResolveImage(
                        radv_CmdBeginRenderPass(cmd_buffer_h,
                                                      &(VkRenderPassBeginInfo) {
                                                              .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
-                                                                     .renderPass = device->meta_state.resolve.pass,
+                                                                     .renderPass = device->meta_state.resolve.pass[fs_key],
                                                                      .framebuffer = fb_h,
                                                                      .renderArea = {
                                                                      .offset = {
@@ -530,6 +559,7 @@ void radv_CmdResolveImage(
                                                      VK_SUBPASS_CONTENTS_INLINE);
 
                        emit_resolve(cmd_buffer,
+                                    dest_iview.vk_format,
                                     &(VkOffset2D) {
                                             .x = dstOffset.x,
                                             .y = dstOffset.y,
@@ -624,6 +654,7 @@ radv_cmd_buffer_resolve_subpass(struct radv_cmd_buffer *cmd_buffer)
                radv_cmd_buffer_set_subpass(cmd_buffer, &resolve_subpass, false);
 
                emit_resolve(cmd_buffer,
+                            dst_img->vk_format,
                             &(VkOffset2D) { 0, 0 },
                             &(VkExtent2D) { fb->width, fb->height });
        }
index fedbb5d29f713b22a97e538411a61a2d97c95622..808db0007dc96586468df3689988c95dde02eeb4 100644 (file)
@@ -478,8 +478,8 @@ struct radv_meta_state {
 
        struct {
                VkPipelineLayout                          p_layout;
-               VkPipeline                                pipeline;
-               VkRenderPass                              pass;
+               VkPipeline                                pipeline[NUM_META_FS_KEYS];
+               VkRenderPass                              pass[NUM_META_FS_KEYS];
        } resolve;
 
        struct {