Commit Graph

294 Commits

Author SHA1 Message Date
Rhys Perry
b85c38a86f spirv: make OpLoad/OpStore visibility/availablity barriers acquire/release
I think these are needed to order the visibility/availability operation
with the access.

Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6090>
2020-09-01 17:15:22 +00:00
Rhys Perry
5b92392c48 spirv: fix Uniform and Output MemoryAccessMakePointer{Visible,Available}
The Uniform storage class can be used for SSBOs. This should also fix make
available/visible for the Output storage class.

Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6090>
2020-09-01 17:15:22 +00:00
Boris Brezillon
857b9c5027 spirv: Add a vtn_get_mem_operands() helper
Add a vtn_get_mem_operands() helper to extract memory operand attached
to load/store operations.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6090>
2020-09-01 17:15:22 +00:00
Jesse Natalie
b778e7bd6c nir/vtn: Convert constant samplers to variables with data
Reviewd-by: Jason Ekstrand <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5242>
2020-08-31 21:17:39 +00:00
Jesse Natalie
368e9a0b54 spirv: Use new global invocation offset system value
Reviewed-by: Karol Herbst <kherbst@redhat.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5891>
2020-08-21 22:07:05 +00:00
Connor Abbott
340c73d4ef nir/spirv: Add the option to keep ViewIndex as an input
This is necessary for fragment shaders on adreno.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5719>
2020-08-19 16:36:43 +00:00
Jason Ekstrand
b479de8537 spirv: Don't emit RMW for vector indexing in shared or global
Anything that fails the is_external_block check is getting the
vtn_local_load/store path which does read-modify-write which isn't
correct if the variable mode can be written cross-workgroup.

Cc: mesa-stable@lists.freedesktop.org
Reviewed-by: Jesse Natalie <jenatali@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6372>
2020-08-18 20:22:05 +00:00
Danylo Piliaiev
b6ebf6eba9 spirv: Only require bare types to match when copying variables
OpCopyMemory doesn't care about mismatched decorations, only about
matching types.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3418
Fixes: bf1a1eed88
Signed-off-by: Danylo Piliaiev <danylo.piliaiev@globallogic.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6344>
2020-08-18 11:53:07 +00:00
Caio Marcelo de Oliveira Filho
b98dd70489 spirv: Propagate explicit layout only in types that need it
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5511>
2020-08-04 07:53:37 -07:00
Jason Ekstrand
63cf8adb12 spirv: Also copy over binding information for atomic counters
I missed this if statement so atomic counters weren't getting bindings
and, when you have more than one of them, that meant they were all
getting combined into one.

Fixes: 3584cb09bc15 "spirv: Give atomic counters their own variable mode"
Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6060>
2020-07-24 18:17:38 +00:00
Jason Ekstrand
14a12b771d spirv: Rework our handling of images and samplers
Previously, objects of type OpTypeImage or OpTypeSampler were treated as
vtn_pointers and objects of type OpTypeSampledImage were a special-use
vtn_sampled_image struct.  This commit changes that so that all of those
objects are stored in vtn_ssa_values.  Each of images, samplers, and
sampled images, are stored as a scalar or vector nir_ssa_def whose
components are NIR deref values.  We now use vtn_type_get_nir_type to
re-resolve those as-needed into GLSL sampler types for NIR.

This simplification has a number of benefits:

 1. We can git rid of the rest of our special-cases for handling images
    and samplers in function arguments.  Now that they're treated as
    structs at the glsl_type level, the generic paths can handle images
    and samplers.

 2. We can now construct composite values containing images and samplers
    internally.  It's unclear from the SPIR-V spec whether or not this
    is allowed and it's not a pattern that GLSLang currently generates
    thanks to GLSL rules.  However, if we do start seeing SPIR-V that
    contains such composites, we should now be able to handle it.

 3. SPIR-V OpNull and OpUndef instructions can now create samplers,
    images, and sampled images.  The NIR generated won't likely be fully
    valid but, given a NIR pass to do something sensible, it should be a
    thing we can compile.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5278>
2020-07-23 22:43:21 -05:00
Jason Ekstrand
9e3213ad30 spirv: Add a helper for getting the NIR type of a vtn_type
There are a few cases, atomic counters being one example, where the type
used by vtn_ssa_value is not the same as the type we want NIR to use in
derefs and variables.  To solve this, we add a helper which converts
between the types for us.  In the next commit, we'll be adding another
major user of this: images and samplers.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5278>
2020-07-23 22:43:21 -05:00
Jason Ekstrand
051f8d3d1c spirv: Give atomic counters their own variable mode
Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5278>
2020-07-23 22:43:21 -05:00
Jason Ekstrand
d0be2fed4e spirv: Add better checks for SSA value types
Primarily, we check for two things:

 1. That we only ever add SSA values via vtn_push_ssa_value and
    vtn_copy_value.

 2. That the type of the SSA value matches the SPIR-V destination type.

Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5278>
2020-07-23 22:43:21 -05:00
Jason Ekstrand
47ebb50cab spirv: Hand-roll fewer vtn_ssa_value creations
Previously, we created our vtn_ssa_value in _vtn_variable_load_store
manually as we did the recursive load/store.  Instead, we now create the
SSA value before calling into the recursive function.  This is a tiny
bit less efficient but it removes a case of hand-rolling vtn_ssa_value
creation.  For symmetry, we make _vtn_block_load_store assume the value
is already created.  Finally, we remove a trivial hand-rolled case in
vtn_composite_extract.

Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5278>
2020-07-23 22:43:21 -05:00
Jason Ekstrand
dbb4a24413 spirv: Refactor vtn_push_ssa
We rename it to vtn_push_ssa_value, move it to spirv_to_nir, and remove
the unnecessary type parameter.

Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5278>
2020-07-23 22:43:21 -05:00
Jason Ekstrand
8be9f2a4f6 spirv: Use the new helpers in OpConvertUToPtr/PtrToU
Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5278>
2020-07-23 22:43:21 -05:00
Jason Ekstrand
d8eb6f2499 spirv: Add a vtn_push_nir_ssa helper
This makes it easy to write a simple NIR SSA value

Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5278>
2020-07-23 22:43:21 -05:00
Jason Ekstrand
aaf1f34215 spirv: Rename push_value_pointer to push_pointer
Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5278>
2020-07-23 22:43:21 -05:00
Jason Ekstrand
ac1e6d5a46 spirv: Add a helpers for getting types of values
Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5278>
2020-07-23 22:43:21 -05:00
Jason Ekstrand
af81486a8c spirv: Simplify our handling of NonUniform
The original implementation of SPV_EXT_descriptor_indexing was extremely
paranoid about the NonUniform qualifier, trying to fetch it from every
possible location and propagate it through access chains etc.  However,
the Vulkan spec is quite nice to us on this and has very strict rules
for where the NonUniform decoration has to be placed.  For image and
texture operations, we can search for the decoration on the spot when we
process the image or texture op.  For pointers, we continue putting it
on the pointer but we don't bother trying to do anything silly like
propagate it through casts.

Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5278>
2020-07-23 22:41:54 -05:00
Jonathan Marek
8453d2941a Revert "nir: Support sysval tess levels in SPIR-V to NIR"
This reverts commit d2d4677b56.

The option is not used by any driver.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5744>
2020-07-06 08:48:10 -04:00
Jonathan Marek
2044bdac4f Revert "nir: Add an option for lowering TessLevelInner/Outer to vecs"
This reverts commit d2df076120.

The option is not used by any driver.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5744>
2020-07-06 08:48:10 -04:00
Rhys Perry
c344c083fc spirv: set variables to restrict by default
Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5207>
2020-06-24 10:52:27 +00:00
Brian Ho
d2df076120 nir: Add an option for lowering TessLevelInner/Outer to vecs
The GLSL to NIR compiler supports the LowerTessLevel flag to convert
gl_TessLevelInner/Outer from their GLSL declarations as arrays of
floats to vec4/vec2s to better match how they are represented in
hardware.

This commit adds the similar support to the SPIR-V to NIR compiler so
turnip can use the same IR3/NIR tess lowering passes as freedreno.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5059>
2020-06-22 14:35:45 +00:00
Brian Ho
d2d4677b56 nir: Support sysval tess levels in SPIR-V to NIR
This commit adds a tess_levels_are_sysvals flag to
spirv_to_nir_options similar to GLSLTessLevelsAsInputs in the GLSL to
NIR compiler options. This will be used by turnip as the tess IR3
lowering pass (ir3_nir_lower_tess) operates on TessLevelInner and
TessLevelOuter in the DS as sysvals.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5059>
2020-06-22 14:35:45 +00:00
Samuel Pitoiset
10c4a7cf59 spirv,radv,anv: implement no-op VK_GOOGLE_user_type
This extension only allows HLSL shader compilers to optionally embed
unambiguous type information which can be safely ignored by the driver.

This fixes a crash with the recent Vulkan backend of Path Of Exile
(it uses the extension without checking if it's supported).

Cc: <mesa-stable@lists.freedesktop.org>
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Tested-by: Edmondo Tommasina <edmondo.tommasina@gmail.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5237>
2020-05-28 17:30:24 +02:00
Samuel Pitoiset
844d561c58 spirv: handle OpCopyObject correctly with any types
This implements OpCopyObject as a blind copy and propagates the
access mask properly even if the source object type isn't a SSA
value.

This fixes some recent dEQP-VK.descriptor_indexing.* failures
since CTS changed and now apply nonUniformEXT after constructing
a combined image/sampler.

Original patch is from Jason Ekstrand.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4909>
2020-05-15 19:18:53 +00:00
Jason Ekstrand
64e4297629 spirv: Allow constants and NULLs in SpvOpConvertUToPtr
We were accidentally asserting that the value had to be a vtn_ssa_value
which isn't true if it, for instance, comes from a spec constant.

Fixes: fb282a68bc "spirv: Implement OpConvertPtrToU and OpConvertUToPtr"
Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Acked-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4675>
2020-04-24 09:23:59 +00:00
Caio Marcelo de Oliveira Filho
a1f6ae4744 spirv: Fix propagation of OpVariable access flags
After the decorations of a variable are evaluated, propagate the
access flag to the associated vtn_pointer.  This was done when
creating the pointer but at that point there was no access flags for
the variable.

Inline the pointer creation to make this point clearer, in isolation
the helper made the impression that the value was being propagated.

Issue found by Ken.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4620>
2020-04-20 16:46:06 +00:00
Jason Ekstrand
f5deed138a spirv,nir: Move the SPIR-V vector insert code to NIR
This also makes spirv_to_nir a bit simpler because the new
nir_vector_insert helper automatically handles a constant component
selector like nir_vector_extract does.

Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4495>
2020-04-17 19:21:44 +00:00
Jason Ekstrand
feca439697 spirv: Call nir_builder directly for vector_extract
The nir_builder helper already handles checking if the component
selector is an immediate and returns an undef in the OOB case.

Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4495>
2020-04-17 19:21:44 +00:00
Arcady Goldmints-Orlov
e459c7f0a1 compiler/spirv: Add support for non-constant initializers
This adds support for OpVariable having an initializer that points to
another variable, rather than a constant. In this case, the variable is
initialized to a pointer to the other variable.

Fixes Vulkan CTS tests:
dEQP-VK.spirv_assembly.instruction.compute.variable_init.private.*

Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3047>
2020-02-12 15:41:49 +00:00
Samuel Pitoiset
df8dd12e5b spirv: add support for SpvBuiltInBaryCoord*
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3578>
2020-01-29 09:49:50 +00:00
Samuel Pitoiset
5c053cc6ec spirv: add support for SpvDecorationExplicitInterpAMD
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3578>
2020-01-29 09:49:50 +00:00
Caio Marcelo de Oliveira Filho
1ec0d4fdff spirv: Drop EXT for PhysicalStorageBuffer symbols
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3322>
2020-01-14 14:42:12 -08:00
Karol Herbst
2402232c90 spirv: handle UniformConstant for OpenCL kernels
The caller is responsible for setting up the ubo_addr_format value as
contrary to shared and global, it's not controlled by the spirv.

Right now clovers implementation of CL constant memory uses a 24/8 bit format
to encode the buffer index and offset, but that code is dead as all backends
treat constants as global memory to workaround annoying issues within OpenCL.

Maybe that will change, maybe not. But just in case somebody wants to look at
it, add a toggle for this inside vtn.

Signed-off-by: Karol Herbst <kherbst@redhat.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
2019-12-11 23:54:39 +00:00
Marek Olšák
ebe7579655 nir: move data.image.access to data.access
The size of the data structure doesn't change.

Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
2019-11-19 18:20:05 -05:00
Caio Marcelo de Oliveira Filho
7ae506e5b8 spirv: Consider the sampled_image case in wa_glslang_179 workaround
Fixes: 9e440b8d0b ("spirv: Sort out the mess that is sampled image")
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
2019-11-13 12:02:29 -08:00
Jason Ekstrand
0c7e0c5599 spirv: Fix the MSVC build
Fixes: 9cc4c2c916 "spirv: Add a vtn_decorate_pointer helper"
Tested-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
2019-11-12 08:34:55 +00:00
Jason Ekstrand
9e440b8d0b spirv: Sort out the mess that is sampled image
This commit makes two major changes.  First, we add a second case to
OpLoad for sampled images which constructs a vtn_sampled_image and
stashes that rather than stashing a pointer to the combined image
sampler like we do for bare samplers and images.  This should be more in
line with how SPIR-V is intended to work and hopefully doesn't cause any
weird problems.  The second is a rework of vtn_handle_texture to assume
that everything has an image but not everything has a sampler.  We also
add a vtn_fail_if for the case where a texture instructions require a
sampler but none is provided.

Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
2019-11-09 15:29:01 +00:00
Jason Ekstrand
9cc4c2c916 spirv: Add a vtn_decorate_pointer helper
This helper makes a duplicate copy of the pointer if any new access
flags are set at this stage.  This way we don't end up propagating
access flags further than they actual SPIR-V decorations.  In several
instances where we create new pointers, we still call the decoration
helper directly because no copy is needed.

Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
2019-11-09 15:29:01 +00:00
Jason Ekstrand
4f9688e571 spirv: Remove the type from sampled_image
We have types on all vtn_values at this point so there's no reason to
carry the redundant type information.

Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
2019-11-09 15:29:01 +00:00
Marek Olšák
4319cc8c0f nir: pack nir_variable::data::xfb_*
Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
2019-11-04 18:17:34 -05:00
Caio Marcelo de Oliveira Filho
b8784fe652 spirv: Handle MakePointerAvailable/Visible
Emit barriers with semantics matching the access operand and the
storage class of the pointer.

v2: Fix order of visible / available emission relative to the
    operations.  (Bas)

Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
2019-10-24 11:39:56 -07:00
Caio Marcelo de Oliveira Filho
5ed4e31c08 spirv: Drop lower_workgroup_access_to_offsets
Intel drivers are not using this anymore, and turnip still don't have
Compute Shaders, so won't make a difference to stop using this option.

Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Acked-by: Rob Clark <robdclark@chromium.org>
2019-08-10 22:15:35 -07:00
Antia Puentes
954224b714 nir/spirv: Fix gl_BaseVertex for non-indexed draws for OpenGL
Lowers BaseVertex to the correct system value for OpenGL.

v2: use options->environment rather than adding a new flag to
    spirv_to_nir_options

Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
2019-08-06 09:11:27 -07:00
Lionel Landwerlin
7deb5ec0e8 spirv: don't discard access set by vtn_pointer_dereference
We can have a access flag already set here so just augment the
existing ones.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Fixes: 0fb61dfdeb ("spirv: propagate access qualifiers through ssa & pointer")
Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
2019-07-30 17:43:59 +00:00
Lionel Landwerlin
0fb61dfdeb spirv: propagate access qualifiers through ssa & pointer
Not only variables can be flagged as NonUniformEXT but also
expressions. We're currently ignoring it in an expression such as :

   imageLoad(data[nonuniformEXT(rIndex)], 0)

The associated SPIRV :

   OpDecorate %69 NonUniformEXT
   ...
   %69 = OpLoad %61 %68

This changes propagates access qualifiers through ssa & pointers so
that when it hits a OpLoad/OpStore style instructions, qualifiers are
not forgotten.

Fixes failure the following tests :

   dEQP-VK.descriptor_indexing.*

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Fixes: 8ed583fe52 ("spirv: Handle the NonUniformEXT decoration")
Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
2019-07-26 14:09:55 +00:00
Lionel Landwerlin
86b53770e1 spirv: wrap push ssa/pointer values
This refactor allows for common code to apply decoration on all
ssa/pointer values. In particular this will allow to propagage access
qualifiers.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Suggested-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
2019-07-26 14:09:55 +00:00