#include "pan_resource.h"
#include "pan_public.h"
#include "pan_util.h"
-#include "pandecode/decode.h"
+#include "decode.h"
#include "pan_context.h"
#include "midgard/midgard_compile.h"
{"msgs", PAN_DBG_MSGS, "Print debug messages"},
{"trace", PAN_DBG_TRACE, "Trace the command stream"},
{"deqp", PAN_DBG_DEQP, "Hacks for dEQP"},
- {"afbc", PAN_DBG_AFBC, "Enable non-conformant AFBC impl"},
+ {"afbc", PAN_DBG_AFBC, "Enable AFBC buffer sharing"},
{"sync", PAN_DBG_SYNC, "Wait for each job's completion and check for any GPU fault"},
{"precompile", PAN_DBG_PRECOMPILE, "Precompile shaders for shader-db"},
- {"fp16", PAN_DBG_FP16, "Enable buggy experimental (don't use!) fp16"},
+ {"nofp16", PAN_DBG_NOFP16, "Disable 16-bit support"},
{"bifrost", PAN_DBG_BIFROST, "Enable experimental Mali G31 and G52 support"},
{"gl3", PAN_DBG_GL3, "Enable experimental GL 3.x implementation, up to 3.3"},
DEBUG_NAMED_VALUE_END
case PIPE_CAP_MAX_RENDER_TARGETS:
case PIPE_CAP_FBFETCH:
case PIPE_CAP_FBFETCH_COHERENT:
- return has_mrt ? 4 : 1;
+ return has_mrt ? 8 : 1;
case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
return 1;
case PIPE_CAP_OCCLUSION_QUERY:
case PIPE_CAP_TGSI_INSTANCEID:
case PIPE_CAP_TEXTURE_MULTISAMPLE:
+ case PIPE_CAP_SURFACE_SAMPLE_COUNT:
case PIPE_CAP_PRIMITIVE_RESTART:
case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX:
return !is_bifrost;
case PIPE_CAP_IMAGE_LOAD_FORMATTED:
case PIPE_CAP_CUBE_MAP_ARRAY:
case PIPE_CAP_COMPUTE:
- case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
return is_deqp;
case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
return is_deqp ? 65536 : 0;
+ case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
case PIPE_CAP_QUERY_TIMESTAMP:
case PIPE_CAP_CONDITIONAL_RENDER:
return is_gl3;
+ /* TODO: Where does this req come from in practice? */
+ case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
+ return 1;
+
case PIPE_CAP_MAX_TEXTURE_2D_SIZE:
return 4096;
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
{
struct panfrost_device *dev = pan_device(screen);
bool is_deqp = dev->debug & PAN_DBG_DEQP;
- bool is_fp16 = dev->debug & PAN_DBG_FP16;
+ bool is_nofp16 = dev->debug & PAN_DBG_NOFP16;
bool is_bifrost = dev->quirks & IS_BIFROST;
if (shader != PIPE_SHADER_VERTEX &&
return 16;
case PIPE_SHADER_CAP_MAX_OUTPUTS:
- return shader == PIPE_SHADER_FRAGMENT ? 4 : 16;
+ return shader == PIPE_SHADER_FRAGMENT ? 8 : 16;
case PIPE_SHADER_CAP_MAX_TEMPS:
return 256; /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
return 1;
case PIPE_SHADER_CAP_FP16:
- return !(dev->quirks & MIDGARD_BROKEN_FP16) || is_fp16;
+ case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:
+ return !is_nofp16;
case PIPE_SHADER_CAP_FP16_DERIVATIVES:
case PIPE_SHADER_CAP_INT16:
- case PIPE_SHADER_CAP_GLSL_16BIT_TEMPS:
case PIPE_SHADER_CAP_INT64_ATOMICS:
case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
if (scanout && renderable && !util_format_is_rgba8_variant(format_desc))
return false;
- if (dev->debug & (PAN_DBG_GL3 | PAN_DBG_DEQP)) {
- if (format_desc->layout == UTIL_FORMAT_LAYOUT_RGTC)
- return true;
- }
-
/* Check we support the format with the given bind */
unsigned relevant_bind = bind &
/* Also check that compressed texture formats are supported on this
* particular chip. They may not be depending on system integration
- * differences. */
+ * differences. RGTC can be emulated so is always supported. */
+
+ bool is_rgtc = format_desc->layout == UTIL_FORMAT_LAYOUT_RGTC;
+ bool supported = panfrost_supports_compressed_format(dev, fmt.hw);
- if (!panfrost_supports_compressed_format(dev, fmt.hw))
+ if (!is_rgtc && !supported)
return false;
return fmt.hw && ((relevant_bind & ~fmt.bind) == 0);
}
+/* We always support linear and tiled operations, both external and internal.
+ * We support AFBC for a subset of formats, and colourspace transform for a
+ * subset of those. */
+
+static void
+panfrost_query_dmabuf_modifiers(struct pipe_screen *screen,
+ enum pipe_format format, int max, uint64_t *modifiers, unsigned
+ int *external_only, int *out_count)
+{
+ /* Query AFBC status */
+ bool afbc = panfrost_format_supports_afbc(format);
+ bool ytr = panfrost_afbc_can_ytr(format);
+
+ /* Don't advertise AFBC before T760 */
+ struct panfrost_device *dev = pan_device(screen);
+ afbc &= !(dev->quirks & MIDGARD_NO_AFBC);
+
+ /* XXX: AFBC scanout is broken on mainline RK3399 with older kernels */
+ afbc &= (dev->debug & PAN_DBG_AFBC);
+
+ unsigned count = 0;
+
+ for (unsigned i = 0; i < PAN_MODIFIER_COUNT; ++i) {
+ if (drm_is_afbc(pan_best_modifiers[i]) && !afbc)
+ continue;
+
+ if ((pan_best_modifiers[i] & AFBC_FORMAT_MOD_YTR) && !ytr)
+ continue;
+
+ count++;
+
+ if (max > (int) count) {
+ modifiers[count] = pan_best_modifiers[i];
+
+ if (external_only)
+ external_only[count] = false;
+ }
+ }
+
+ *out_count = count;
+}
+
static int
panfrost_get_compute_param(struct pipe_screen *pscreen, enum pipe_shader_ir ir_type,
enum pipe_compute_cap param, void *ret)
struct pipe_fence_handle **ptr,
struct pipe_fence_handle *fence)
{
+ struct panfrost_device *dev = pan_device(pscreen);
struct panfrost_fence **p = (struct panfrost_fence **)ptr;
struct panfrost_fence *f = (struct panfrost_fence *)fence;
struct panfrost_fence *old = *p;
if (pipe_reference(&(*p)->reference, &f->reference)) {
- util_dynarray_foreach(&old->syncfds, int, fd)
- close(*fd);
- util_dynarray_fini(&old->syncfds);
+ drmSyncobjDestroy(dev->fd, old->syncobj);
free(old);
}
*p = f;
{
struct panfrost_device *dev = pan_device(pscreen);
struct panfrost_fence *f = (struct panfrost_fence *)fence;
- struct util_dynarray syncobjs;
int ret;
- /* All fences were already signaled */
- if (!util_dynarray_num_elements(&f->syncfds, int))
+ if (f->signaled)
return true;
- util_dynarray_init(&syncobjs, NULL);
- util_dynarray_foreach(&f->syncfds, int, fd) {
- uint32_t syncobj;
-
- ret = drmSyncobjCreate(dev->fd, 0, &syncobj);
- assert(!ret);
-
- ret = drmSyncobjImportSyncFile(dev->fd, syncobj, *fd);
- assert(!ret);
- util_dynarray_append(&syncobjs, uint32_t, syncobj);
- }
-
uint64_t abs_timeout = os_time_get_absolute_timeout(timeout);
if (abs_timeout == OS_TIMEOUT_INFINITE)
abs_timeout = INT64_MAX;
- ret = drmSyncobjWait(dev->fd, util_dynarray_begin(&syncobjs),
- util_dynarray_num_elements(&syncobjs, uint32_t),
+ ret = drmSyncobjWait(dev->fd, &f->syncobj,
+ 1,
abs_timeout, DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL,
NULL);
- util_dynarray_foreach(&syncobjs, uint32_t, syncobj)
- drmSyncobjDestroy(dev->fd, *syncobj);
-
- return ret >= 0;
+ f->signaled = (ret >= 0);
+ return f->signaled;
}
struct panfrost_fence *
panfrost_fence_create(struct panfrost_context *ctx,
- struct util_dynarray *fences)
+ uint32_t syncobj)
{
- struct panfrost_device *device = pan_device(ctx->base.screen);
struct panfrost_fence *f = calloc(1, sizeof(*f));
if (!f)
return NULL;
- util_dynarray_init(&f->syncfds, NULL);
-
- /* Export fences from all pending batches. */
- util_dynarray_foreach(fences, struct panfrost_batch_fence *, fence) {
- int fd = -1;
-
- /* The fence is already signaled, no need to export it. */
- if ((*fence)->signaled)
- continue;
-
- drmSyncobjExportSyncFile(device->fd, (*fence)->syncobj, &fd);
- if (fd == -1)
- fprintf(stderr, "export failed: %m\n");
-
- assert(fd != -1);
- util_dynarray_append(&f->syncfds, int, fd);
- }
-
pipe_reference_init(&f->reference, 1);
+ f->syncobj = syncobj;
return f;
}
screen->base.get_paramf = panfrost_get_paramf;
screen->base.get_timestamp = panfrost_get_timestamp;
screen->base.is_format_supported = panfrost_is_format_supported;
+ screen->base.query_dmabuf_modifiers = panfrost_query_dmabuf_modifiers;
screen->base.context_create = panfrost_create_context;
screen->base.get_compiler_options = panfrost_screen_get_compiler_options;
screen->base.fence_reference = panfrost_fence_reference;