turnip: implement border color
authorJonathan Marek <jonathan@marek.ca>
Fri, 15 Nov 2019 17:42:44 +0000 (12:42 -0500)
committerJonathan Marek <jonathan@marek.ca>
Fri, 6 Dec 2019 03:12:30 +0000 (22:12 -0500)
Fixes the deqp fails in:
dEQP-VK.pipeline.sampler.*border*
(minus 1d array/d24 cases which fail for other reasons)

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Kristian H. Kristensen <hoegsberg@google.com>
src/freedreno/vulkan/tu_cmd_buffer.c
src/freedreno/vulkan/tu_device.c
src/freedreno/vulkan/tu_private.h

index 3759629165c59c5db77463b540ae977676e83afc..2ab38ecc60b5eedcf23d9c93b9675b86fab0805a 100644 (file)
@@ -2583,29 +2583,96 @@ tu6_emit_ibo(struct tu_device *device, struct tu_cs *draw_state,
    return tu_cs_end_sub_stream(draw_state, &cs);
 }
 
-static void
+struct PACKED bcolor_entry {
+   uint32_t fp32[4];
+   uint16_t ui16[4];
+   int16_t  si16[4];
+   uint16_t fp16[4];
+   uint16_t rgb565;
+   uint16_t rgb5a1;
+   uint16_t rgba4;
+   uint8_t __pad0[2];
+   uint8_t  ui8[4];
+   int8_t   si8[4];
+   uint32_t rgb10a2;
+   uint32_t z24; /* also s8? */
+   uint16_t srgb[4];      /* appears to duplicate fp16[], but clamped, used for srgb */
+   uint8_t  __pad1[56];
+} border_color[] = {
+   [VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK] = {},
+   [VK_BORDER_COLOR_INT_TRANSPARENT_BLACK] = {},
+   [VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK] = {
+      .fp32[3] = 0x3f800000,
+      .ui16[3] = 0xffff,
+      .si16[3] = 0x7fff,
+      .fp16[3] = 0x3c00,
+      .rgb5a1 = 0x8000,
+      .rgba4 = 0xf000,
+      .ui8[3] = 0xff,
+      .si8[3] = 0x7f,
+      .rgb10a2 = 0xc0000000,
+      .srgb[3] = 0x3c00,
+   },
+   [VK_BORDER_COLOR_INT_OPAQUE_BLACK] = {
+      .fp32[3] = 1,
+      .fp16[3] = 1,
+   },
+   [VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE] = {
+      .fp32[0 ... 3] = 0x3f800000,
+      .ui16[0 ... 3] = 0xffff,
+      .si16[0 ... 3] = 0x7fff,
+      .fp16[0 ... 3] = 0x3c00,
+      .rgb565 = 0xffff,
+      .rgb5a1 = 0xffff,
+      .rgba4 = 0xffff,
+      .ui8[0 ... 3] = 0xff,
+      .si8[0 ... 3] = 0x7f,
+      .rgb10a2 = 0xffffffff,
+      .z24 = 0xffffff,
+      .srgb[0 ... 3] = 0x3c00,
+   },
+   [VK_BORDER_COLOR_INT_OPAQUE_WHITE] = {
+      .fp32[0 ... 3] = 1,
+      .fp16[0 ... 3] = 1,
+   },
+};
+
+static VkResult
 tu6_emit_border_color(struct tu_cmd_buffer *cmd,
                       struct tu_cs *cs)
 {
-   const struct tu_pipeline *pipeline = cmd->state.pipeline;
-
-#define A6XX_BORDER_COLOR_DWORDS (128/4)
-   uint32_t size = A6XX_BORDER_COLOR_DWORDS *
-      (pipeline->program.link[MESA_SHADER_VERTEX].sampler_map.num +
-       pipeline->program.link[MESA_SHADER_FRAGMENT].sampler_map.num) +
-      A6XX_BORDER_COLOR_DWORDS - 1; /* room for alignment */
+   STATIC_ASSERT(sizeof(struct bcolor_entry) == 128);
 
-   struct tu_cs border_cs;
-   tu_cs_begin_sub_stream(cmd->device, &cmd->draw_state, size, &border_cs);
+   const struct tu_pipeline *pipeline = cmd->state.pipeline;
+   struct tu_descriptor_state *descriptors_state =
+      &cmd->descriptors[VK_PIPELINE_BIND_POINT_GRAPHICS];
+   const struct tu_descriptor_map *vs_sampler =
+      &pipeline->program.link[MESA_SHADER_VERTEX].sampler_map;
+   const struct tu_descriptor_map *fs_sampler =
+      &pipeline->program.link[MESA_SHADER_FRAGMENT].sampler_map;
+   struct ts_cs_memory ptr;
+
+   VkResult result = tu_cs_alloc(cmd->device, &cmd->draw_state,
+                                 vs_sampler->num + fs_sampler->num, 128 / 4,
+                                 &ptr);
+   if (result != VK_SUCCESS)
+      return result;
 
-   /* TODO: actually fill with border color */
-   for (unsigned i = 0; i < size; i++)
-      tu_cs_emit(&border_cs, 0);
+   for (unsigned i = 0; i < vs_sampler->num; i++) {
+      struct tu_sampler *sampler = sampler_ptr(descriptors_state, vs_sampler, i);
+      memcpy(ptr.map, &border_color[sampler->border], 128);
+      ptr.map += 128 / 4;
+   }
 
-   struct tu_cs_entry entry = tu_cs_end_sub_stream(&cmd->draw_state, &border_cs);
+   for (unsigned i = 0; i < fs_sampler->num; i++) {
+      struct tu_sampler *sampler = sampler_ptr(descriptors_state, fs_sampler, i);
+      memcpy(ptr.map, &border_color[sampler->border], 128);
+      ptr.map += 128 / 4;
+   }
 
    tu_cs_emit_pkt4(cs, REG_A6XX_SP_TP_BORDER_COLOR_BASE_ADDR_LO, 2);
-       tu_cs_emit_qw(cs, align(entry.bo->iova + entry.offset, 128));
+   tu_cs_emit_qw(cs, ptr.iova);
+   return VK_SUCCESS;
 }
 
 static VkResult
@@ -2778,8 +2845,11 @@ tu6_bind_draw_states(struct tu_cmd_buffer *cmd,
                                descriptors_state, MESA_SHADER_FRAGMENT)
          };
 
-      if (needs_border)
-         tu6_emit_border_color(cmd, cs);
+      if (needs_border) {
+         result = tu6_emit_border_color(cmd, cs);
+         if (result != VK_SUCCESS)
+            return result;
+      }
    }
 
    tu_cs_emit_pkt7(cs, CP_SET_DRAW_STATE, 3 * draw_state_group_count);
index 8a350a054b6532ae6cb8d15decada06eb44e820d..645fcd31648ec8d2cfb6f174f91c39a1642b17c6 100644 (file)
@@ -1959,6 +1959,7 @@ tu_init_sampler(struct tu_device *device,
     */
 
    sampler->needs_border = needs_border;
+   sampler->border = pCreateInfo->borderColor;
 }
 
 VkResult
index 4f2b9fefad5c2c26963e31dc08e01bf1c3196331..65398471644ce6ae7f9d5511c76fd87fdb3ac197 100644 (file)
@@ -1400,6 +1400,7 @@ struct tu_sampler
    uint32_t state[A6XX_TEX_SAMP_DWORDS];
 
    bool needs_border;
+   VkBorderColor border;
 };
 
 VkResult