tu_cs_emit_regs(cs,
A6XX_RB_LRZ_CNTL(0));
+ tu_cs_emit_regs(cs,
+ A6XX_SP_TP_BORDER_COLOR_BASE_ADDR(.bo = &cmd->device->border_color));
+
tu_cs_sanity_check(cs);
}
MSM_SUBMIT_BO_READ | MSM_SUBMIT_BO_WRITE);
}
+ tu_bo_list_add(&cmd_buffer->bo_list, &cmd_buffer->device->border_color,
+ MSM_SUBMIT_BO_READ);
+
for (uint32_t i = 0; i < cmd_buffer->draw_cs.bo_count; i++) {
tu_bo_list_add(&cmd_buffer->bo_list, cmd_buffer->draw_cs.bos[i],
MSM_SUBMIT_BO_READ | MSM_SUBMIT_BO_DUMP);
struct tu_cs_entry ib;
};
-const static struct tu_sampler*
+const static void *
sampler_ptr(struct tu_descriptor_state *descriptors_state,
const struct tu_descriptor_map *map, unsigned i,
unsigned array_index)
&set->layout->binding[map->binding[i]];
if (layout->immutable_samplers_offset) {
- const struct tu_sampler *immutable_samplers =
+ const uint32_t *immutable_samplers =
tu_immutable_samplers(set->layout, layout);
- return &immutable_samplers[array_index];
+ return &immutable_samplers[array_index * A6XX_TEX_SAMP_DWORDS];
}
switch (layout->type) {
case VK_DESCRIPTOR_TYPE_SAMPLER:
- return (struct tu_sampler*) &set->mapped_ptr[layout->offset / 4];
+ return &set->mapped_ptr[layout->offset / 4];
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
- return (struct tu_sampler*) &set->mapped_ptr[layout->offset / 4 + A6XX_TEX_CONST_DWORDS +
- array_index *
- (A6XX_TEX_CONST_DWORDS +
- sizeof(struct tu_sampler) / 4)];
+ return &set->mapped_ptr[layout->offset / 4 + A6XX_TEX_CONST_DWORDS +
+ array_index * (A6XX_TEX_CONST_DWORDS + A6XX_TEX_SAMP_DWORDS)];
default:
unreachable("unimplemented descriptor type");
break;
memcpy(dst, &set->mapped_ptr[layout->offset / 4 +
array_index *
(A6XX_TEX_CONST_DWORDS +
- sizeof(struct tu_sampler) / 4)],
+ A6XX_TEX_SAMP_DWORDS)],
A6XX_TEX_CONST_DWORDS * 4);
break;
default:
struct tu_descriptor_state *descriptors_state,
gl_shader_stage type,
struct tu_cs_entry *entry,
- bool *needs_border,
bool is_sysmem)
{
struct tu_cs *draw_state = &cmd->sub_cs;
int sampler_index = 0;
for (unsigned i = 0; i < link->sampler_map.num; i++) {
for (int j = 0; j < link->sampler_map.array_size[i]; j++) {
- const struct tu_sampler *sampler = sampler_ptr(descriptors_state,
- &link->sampler_map,
- i, j);
+ const uint32_t *sampler = sampler_ptr(descriptors_state,
+ &link->sampler_map,
+ i, j);
memcpy(&tex_samp.map[A6XX_TEX_SAMP_DWORDS * sampler_index++],
- sampler->state, sizeof(sampler->state));
- *needs_border |= sampler->needs_border;
+ sampler, A6XX_TEX_SAMP_DWORDS * 4);
}
}
}
return VK_SUCCESS;
}
-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)
-{
- STATIC_ASSERT(sizeof(struct bcolor_entry) == 128);
-
- 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->sub_cs,
- vs_sampler->num_desc + fs_sampler->num_desc,
- 128 / 4,
- &ptr);
- if (result != VK_SUCCESS)
- return result;
-
- for (unsigned i = 0; i < vs_sampler->num; i++) {
- for (unsigned j = 0; j < vs_sampler->array_size[i]; j++) {
- const struct tu_sampler *sampler = sampler_ptr(descriptors_state,
- vs_sampler, i, j);
- memcpy(ptr.map, &border_color[sampler->border], 128);
- ptr.map += 128 / 4;
- }
- }
-
- for (unsigned i = 0; i < fs_sampler->num; i++) {
- for (unsigned j = 0; j < fs_sampler->array_size[i]; j++) {
- const struct tu_sampler *sampler = sampler_ptr(descriptors_state,
- fs_sampler, i, j);
- 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, ptr.iova);
- return VK_SUCCESS;
-}
-
static void
tu6_emit_streamout(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
{
if (cmd->state.dirty &
(TU_CMD_DIRTY_PIPELINE | TU_CMD_DIRTY_DESCRIPTOR_SETS)) {
- bool needs_border = false;
struct tu_cs_entry vs_tex, fs_tex_sysmem, fs_tex_gmem, fs_ibo;
result = tu6_emit_textures(cmd, pipeline, descriptors_state,
- MESA_SHADER_VERTEX, &vs_tex, &needs_border,
- false);
+ MESA_SHADER_VERTEX, &vs_tex, false);
if (result != VK_SUCCESS)
return result;
* attachments.
*/
result = tu6_emit_textures(cmd, pipeline, descriptors_state,
- MESA_SHADER_FRAGMENT, &fs_tex_sysmem,
- &needs_border, true);
+ MESA_SHADER_FRAGMENT, &fs_tex_sysmem, true);
if (result != VK_SUCCESS)
return result;
result = tu6_emit_textures(cmd, pipeline, descriptors_state,
- MESA_SHADER_FRAGMENT, &fs_tex_gmem,
- &needs_border, false);
+ MESA_SHADER_FRAGMENT, &fs_tex_gmem, false);
if (result != VK_SUCCESS)
return result;
.enable_mask = ENABLE_DRAW,
.ib = fs_ibo,
};
-
- if (needs_border) {
- result = tu6_emit_border_color(cmd, cs);
- if (result != VK_SUCCESS)
- return result;
- }
}
struct tu_cs_entry vs_params;
tu_emit_compute_driver_params(cs, pipeline, info);
- bool needs_border;
result = tu6_emit_textures(cmd, pipeline, descriptors_state,
- MESA_SHADER_COMPUTE, &ib, &needs_border, false);
+ MESA_SHADER_COMPUTE, &ib, false);
if (result != VK_SUCCESS) {
cmd->record_result = result;
return;
if (ib.size)
tu_cs_emit_ib(cs, &ib);
- if (needs_border)
- tu_finishme("compute border color");
-
result = tu6_emit_ibo(cmd, pipeline, descriptors_state, MESA_SHADER_COMPUTE, &ib);
if (result != VK_SUCCESS) {
cmd->record_result = result;
return -1;
}
+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,
+ },
+};
+
+
VkResult
tu_CreateDevice(VkPhysicalDevice physicalDevice,
const VkDeviceCreateInfo *pCreateInfo,
if (result != VK_SUCCESS)
goto fail_vsc_data2;
+ STATIC_ASSERT(sizeof(struct bcolor_entry) == 128);
+ result = tu_bo_init_new(device, &device->border_color, sizeof(border_color));
+ if (result != VK_SUCCESS)
+ goto fail_border_color;
+
+ result = tu_bo_map(device, &device->border_color);
+ if (result != VK_SUCCESS)
+ goto fail_border_color_map;
+
+ memcpy(device->border_color.map, border_color, sizeof(border_color));
+
VkPipelineCacheCreateInfo ci;
ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
ci.pNext = NULL;
return VK_SUCCESS;
fail_pipeline_cache:
+fail_border_color_map:
+ tu_bo_finish(device, &device->border_color);
+
+fail_border_color:
tu_bo_finish(device, &device->vsc_data2);
fail_vsc_data2:
}
static enum a6xx_tex_clamp
-tu6_tex_wrap(VkSamplerAddressMode address_mode, bool *needs_border)
+tu6_tex_wrap(VkSamplerAddressMode address_mode)
{
switch (address_mode) {
case VK_SAMPLER_ADDRESS_MODE_REPEAT:
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:
return A6XX_TEX_CLAMP_TO_EDGE;
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER:
- *needs_border = true;
return A6XX_TEX_CLAMP_TO_BORDER;
case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:
/* only works for PoT.. need to emulate otherwise! */
unsigned aniso = pCreateInfo->anisotropyEnable ?
util_last_bit(MIN2((uint32_t)pCreateInfo->maxAnisotropy >> 1, 8)) : 0;
bool miplinear = (pCreateInfo->mipmapMode == VK_SAMPLER_MIPMAP_MODE_LINEAR);
- bool needs_border = false;
- sampler->state[0] =
+ sampler->descriptor[0] =
COND(miplinear, A6XX_TEX_SAMP_0_MIPFILTER_LINEAR_NEAR) |
A6XX_TEX_SAMP_0_XY_MAG(tu6_tex_filter(pCreateInfo->magFilter, aniso)) |
A6XX_TEX_SAMP_0_XY_MIN(tu6_tex_filter(pCreateInfo->minFilter, aniso)) |
A6XX_TEX_SAMP_0_ANISO(aniso) |
- A6XX_TEX_SAMP_0_WRAP_S(tu6_tex_wrap(pCreateInfo->addressModeU, &needs_border)) |
- A6XX_TEX_SAMP_0_WRAP_T(tu6_tex_wrap(pCreateInfo->addressModeV, &needs_border)) |
- A6XX_TEX_SAMP_0_WRAP_R(tu6_tex_wrap(pCreateInfo->addressModeW, &needs_border)) |
+ A6XX_TEX_SAMP_0_WRAP_S(tu6_tex_wrap(pCreateInfo->addressModeU)) |
+ A6XX_TEX_SAMP_0_WRAP_T(tu6_tex_wrap(pCreateInfo->addressModeV)) |
+ A6XX_TEX_SAMP_0_WRAP_R(tu6_tex_wrap(pCreateInfo->addressModeW)) |
A6XX_TEX_SAMP_0_LOD_BIAS(pCreateInfo->mipLodBias);
- sampler->state[1] =
+ sampler->descriptor[1] =
/* COND(!cso->seamless_cube_map, A6XX_TEX_SAMP_1_CUBEMAPSEAMLESSFILTOFF) | */
COND(pCreateInfo->unnormalizedCoordinates, A6XX_TEX_SAMP_1_UNNORM_COORDS) |
A6XX_TEX_SAMP_1_MIN_LOD(pCreateInfo->minLod) |
A6XX_TEX_SAMP_1_MAX_LOD(pCreateInfo->maxLod) |
COND(pCreateInfo->compareEnable,
A6XX_TEX_SAMP_1_COMPARE_FUNC(tu6_compare_func(pCreateInfo->compareOp)));
- sampler->state[2] = 0;
- sampler->state[3] = 0;
+ /* This is an offset into the border_color BO, which we fill with all the
+ * possible Vulkan border colors in the correct order, so we can just use
+ * the Vulkan enum with no translation necessary.
+ */
+ sampler->descriptor[2] =
+ A6XX_TEX_SAMP_2_BCOLOR_OFFSET((unsigned) pCreateInfo->borderColor *
+ sizeof(struct bcolor_entry));
+ sampler->descriptor[3] = 0;
/* TODO:
* A6XX_TEX_SAMP_1_MIPFILTER_LINEAR_FAR disables mipmapping, but vk has no NONE mipfilter?
- * border color
*/
-
- sampler->needs_border = needs_border;
- sampler->border = pCreateInfo->borderColor;
}
VkResult