diff options
author | Jason Ekstrand <[email protected]> | 2019-03-30 21:00:26 -0500 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2019-04-11 18:04:09 +0000 |
commit | d17dd46b09597827db280aa0b17deef5dd0eead4 (patch) | |
tree | 7624fff1a25b91f744627b35c2c0da8bbf53fea9 /src/intel/common | |
parent | bacb21fc6b32ef14ed022046f9a333640a11452b (diff) |
anv: Move mi_memcpy and mi_memset to gen_mi_builder
Reviewed-by: Lionel Landwerlin <[email protected]>
Diffstat (limited to 'src/intel/common')
-rw-r--r-- | src/intel/common/gen_mi_builder.h | 45 | ||||
-rw-r--r-- | src/intel/common/tests/gen_mi_builder_test.cpp | 30 |
2 files changed, 75 insertions, 0 deletions
diff --git a/src/intel/common/gen_mi_builder.h b/src/intel/common/gen_mi_builder.h index 3dd8fcb739c..22c0aee3343 100644 --- a/src/intel/common/gen_mi_builder.h +++ b/src/intel/common/gen_mi_builder.h @@ -450,6 +450,51 @@ gen_mi_store(struct gen_mi_builder *b, gen_mi_value_unref(b, dst); } +static inline void +gen_mi_memset(struct gen_mi_builder *b, __gen_address_type dst, + uint32_t value, uint32_t size) +{ +#if GEN_GEN >= 8 || GEN_IS_HASWELL + assert(b->num_math_dwords == 0); +#endif + + /* This memset operates in units of dwords. */ + assert(size % 4 == 0); + + for (uint32_t i = 0; i < size; i += 4) { + gen_mi_store(b, gen_mi_mem32(__gen_address_offset(dst, i)), + gen_mi_imm(value)); + } +} + +/* NOTE: On IVB, this function stomps GEN7_3DPRIM_BASE_VERTEX */ +static inline void +gen_mi_memcpy(struct gen_mi_builder *b, __gen_address_type dst, + __gen_address_type src, uint32_t size) +{ +#if GEN_GEN >= 8 || GEN_IS_HASWELL + assert(b->num_math_dwords == 0); +#endif + + /* This memcpy operates in units of dwords. */ + assert(size % 4 == 0); + + for (uint32_t i = 0; i < size; i += 4) { + struct gen_mi_value dst_val = gen_mi_mem32(__gen_address_offset(dst, i)); + struct gen_mi_value src_val = gen_mi_mem32(__gen_address_offset(src, i)); +#if GEN_GEN >= 8 || GEN_IS_HASWELL + gen_mi_store(b, dst_val, src_val); +#else + /* IVB does not have a general purpose register for command streamer + * commands. Therefore, we use an alternate temporary register. + */ + struct gen_mi_value tmp_reg = gen_mi_reg32(0x2440); /* GEN7_3DPRIM_BASE_VERTEX */ + gen_mi_store(b, tmp_reg, src_val); + gen_mi_store(b, dst_val, tmp_reg); +#endif + } +} + /* * MI_MATH Section. Only available on Haswell+ */ diff --git a/src/intel/common/tests/gen_mi_builder_test.cpp b/src/intel/common/tests/gen_mi_builder_test.cpp index e68d35c9fb9..d192e063d00 100644 --- a/src/intel/common/tests/gen_mi_builder_test.cpp +++ b/src/intel/common/tests/gen_mi_builder_test.cpp @@ -422,6 +422,36 @@ TEST_F(gen_mi_builder_test, mem_reg) EXPECT_EQ(*(uint64_t *)(output + 24), (uint64_t)(uint32_t)value); } +TEST_F(gen_mi_builder_test, memset) +{ + const unsigned memset_size = 256; + + gen_mi_memset(&b, out_addr(0), 0xdeadbeef, memset_size); + + submit_batch(); + + uint32_t *out_u32 = (uint32_t *)output; + for (unsigned i = 0; i < memset_size / sizeof(*out_u32); i++) + EXPECT_EQ(out_u32[i], 0xdeadbeef); +} + +TEST_F(gen_mi_builder_test, memcpy) +{ + const unsigned memcpy_size = 256; + + uint8_t *in_u8 = (uint8_t *)input; + for (unsigned i = 0; i < memcpy_size; i++) + in_u8[i] = i; + + gen_mi_memcpy(&b, out_addr(0), in_addr(0), 256); + + submit_batch(); + + uint8_t *out_u8 = (uint8_t *)output; + for (unsigned i = 0; i < memcpy_size; i++) + EXPECT_EQ(out_u8[i], i); +} + /* Start of MI_MATH section */ #if GEN_GEN >= 8 || GEN_IS_HASWELL |