Most of the time we use macros that handle this situation transparently,
but there are some cases were we need to handle this explicitly.
This patch makes sure we don't crash, notice that error handling takes
place in the function that actually failed the allocation,
anv_batch_emit_dwords(), which will set the status field of the batch
so it can be used at a later moment to report the error to the user.
v2:
- Not crashing is not good enough, we need to keep track of the error
(Topi, Jason). Iago: now that we track errors in the batch, this
is being handled.
- Added guards in a few more places that needed it (Iago)
v3:
- Check result of anv_batch_emitn() for NULL before calling memset()
in emit_vertex_input() (Topi)
Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
_blorp_cmd_pack(cmd)(batch, (void *)_dst, &name), \
_dst = NULL)
_blorp_cmd_pack(cmd)(batch, (void *)_dst, &name), \
_dst = NULL)
-#define blorp_emitn(batch, cmd, n) ({ \
- uint32_t *_dw = blorp_emit_dwords(batch, n); \
- struct cmd template = { \
- _blorp_cmd_header(cmd), \
- .DWordLength = n - _blorp_cmd_length_bias(cmd), \
- }; \
- _blorp_cmd_pack(cmd)(batch, _dw, &template); \
- _dw + 1; /* Array starts at dw[1] */ \
+#define blorp_emitn(batch, cmd, n) ({ \
+ uint32_t *_dw = blorp_emit_dwords(batch, n); \
+ if (_dw) { \
+ struct cmd template = { \
+ _blorp_cmd_header(cmd), \
+ .DWordLength = n - _blorp_cmd_length_bias(cmd), \
+ }; \
+ _blorp_cmd_pack(cmd)(batch, _dw, &template); \
+ } \
+ _dw ? _dw + 1 : NULL; /* Array starts at dw[1] */ \
const unsigned num_dwords = 1 + GENX(VERTEX_BUFFER_STATE_length) * 2;
uint32_t *dw = blorp_emitn(batch, GENX(3DSTATE_VERTEX_BUFFERS), num_dwords);
const unsigned num_dwords = 1 + GENX(VERTEX_BUFFER_STATE_length) * 2;
uint32_t *dw = blorp_emitn(batch, GENX(3DSTATE_VERTEX_BUFFERS), num_dwords);
for (unsigned i = 0; i < 2; i++) {
GENX(VERTEX_BUFFER_STATE_pack)(batch, dw, &vb[i]);
for (unsigned i = 0; i < 2; i++) {
GENX(VERTEX_BUFFER_STATE_pack)(batch, dw, &vb[i]);
const unsigned num_dwords =
1 + GENX(VERTEX_ELEMENT_STATE_length) * num_elements;
uint32_t *dw = blorp_emitn(batch, GENX(3DSTATE_VERTEX_ELEMENTS), num_dwords);
const unsigned num_dwords =
1 + GENX(VERTEX_ELEMENT_STATE_length) * num_elements;
uint32_t *dw = blorp_emitn(batch, GENX(3DSTATE_VERTEX_ELEMENTS), num_dwords);
for (unsigned i = 0; i < num_elements; i++) {
GENX(VERTEX_ELEMENT_STATE_pack)(batch, dw, &ve[i]);
for (unsigned i = 0; i < num_elements; i++) {
GENX(VERTEX_ELEMENT_STATE_pack)(batch, dw, &ve[i]);
uint32_t offset = 0;
uint32_t *dw = blorp_emit_dwords(batch,
GENX(3DSTATE_WM_DEPTH_STENCIL_length));
uint32_t offset = 0;
uint32_t *dw = blorp_emit_dwords(batch,
GENX(3DSTATE_WM_DEPTH_STENCIL_length));
GENX(3DSTATE_WM_DEPTH_STENCIL_pack)(NULL, dw, &ds);
#else
uint32_t offset;
GENX(3DSTATE_WM_DEPTH_STENCIL_pack)(NULL, dw, &ds);
#else
uint32_t offset;
VG(VALGRIND_CHECK_MEM_IS_DEFINED(dst, __anv_cmd_length(struc) * 4)); \
} while (0)
VG(VALGRIND_CHECK_MEM_IS_DEFINED(dst, __anv_cmd_length(struc) * 4)); \
} while (0)
-#define anv_batch_emitn(batch, n, cmd, ...) ({ \
- void *__dst = anv_batch_emit_dwords(batch, n); \
- struct cmd __template = { \
- __anv_cmd_header(cmd), \
- .DWordLength = n - __anv_cmd_length_bias(cmd), \
- __VA_ARGS__ \
- }; \
- __anv_cmd_pack(cmd)(batch, __dst, &__template); \
- __dst; \
+#define anv_batch_emitn(batch, n, cmd, ...) ({ \
+ void *__dst = anv_batch_emit_dwords(batch, n); \
+ if (__dst) { \
+ struct cmd __template = { \
+ __anv_cmd_header(cmd), \
+ .DWordLength = n - __anv_cmd_length_bias(cmd), \
+ __VA_ARGS__ \
+ }; \
+ __anv_cmd_pack(cmd)(batch, __dst, &__template); \
+ } \
+ __dst; \
})
#define anv_batch_emit_merge(batch, dwords0, dwords1) \
})
#define anv_batch_emit_merge(batch, dwords0, dwords1) \
\
STATIC_ASSERT(ARRAY_SIZE(dwords0) == ARRAY_SIZE(dwords1)); \
dw = anv_batch_emit_dwords((batch), ARRAY_SIZE(dwords0)); \
\
STATIC_ASSERT(ARRAY_SIZE(dwords0) == ARRAY_SIZE(dwords1)); \
dw = anv_batch_emit_dwords((batch), ARRAY_SIZE(dwords0)); \
for (uint32_t i = 0; i < ARRAY_SIZE(dwords0); i++) \
dw[i] = (dwords0)[i] | (dwords1)[i]; \
VG(VALGRIND_CHECK_MEM_IS_DEFINED(dw, ARRAY_SIZE(dwords0) * 4));\
for (uint32_t i = 0; i < ARRAY_SIZE(dwords0); i++) \
dw[i] = (dwords0)[i] | (dwords1)[i]; \
VG(VALGRIND_CHECK_MEM_IS_DEFINED(dw, ARRAY_SIZE(dwords0) * 4));\
const uint32_t num_dwords = 1 + total_elems * 2;
p = anv_batch_emitn(&pipeline->batch, num_dwords,
GENX(3DSTATE_VERTEX_ELEMENTS));
const uint32_t num_dwords = 1 + total_elems * 2;
p = anv_batch_emitn(&pipeline->batch, num_dwords,
GENX(3DSTATE_VERTEX_ELEMENTS));
memset(p + 1, 0, (num_dwords - 1) * 4);
for (uint32_t i = 0; i < info->vertexAttributeDescriptionCount; i++) {
memset(p + 1, 0, (num_dwords - 1) * 4);
for (uint32_t i = 0; i < info->vertexAttributeDescriptionCount; i++) {
uint32_t *dw = anv_batch_emit_dwords(&pipeline->batch,
GENX(3DSTATE_SBE_length));
uint32_t *dw = anv_batch_emit_dwords(&pipeline->batch,
GENX(3DSTATE_SBE_length));
GENX(3DSTATE_SBE_pack)(&pipeline->batch, dw, &sbe);
#if GEN_GEN >= 8
dw = anv_batch_emit_dwords(&pipeline->batch, GENX(3DSTATE_SBE_SWIZ_length));
GENX(3DSTATE_SBE_pack)(&pipeline->batch, dw, &sbe);
#if GEN_GEN >= 8
dw = anv_batch_emit_dwords(&pipeline->batch, GENX(3DSTATE_SBE_SWIZ_length));
GENX(3DSTATE_SBE_SWIZ_pack)(&pipeline->batch, dw, &swiz);
#endif
}
GENX(3DSTATE_SBE_SWIZ_pack)(&pipeline->batch, dw, &swiz);
#endif
}