On 10/28/2013 03:08 PM, Eric Anholt wrote: > Kenneth Graunke <kenn...@whitecape.org> writes: > >> With Linux 3.12, register writes work on Ivybridge and Baytrail, but not >> Haswell. That will be fixed in a future kernel revision, at which point >> this extension will automatically be enabled. >> >> Signed-off-by: Kenneth Graunke <kenn...@whitecape.org> >> --- >> src/mesa/drivers/dri/i965/intel_extensions.c | 61 >> +++++++++++++++++++++++++++- >> 1 file changed, 60 insertions(+), 1 deletion(-) >> >> Tested on Ivybridge (extension is on) and Haswell (extension is off). >> So the register write testing is working as expected. >> >> diff --git a/src/mesa/drivers/dri/i965/intel_extensions.c >> b/src/mesa/drivers/dri/i965/intel_extensions.c >> index 22e4aa2..0c6ed02 100644 >> --- a/src/mesa/drivers/dri/i965/intel_extensions.c >> +++ b/src/mesa/drivers/dri/i965/intel_extensions.c >> @@ -28,11 +28,68 @@ >> #include "main/version.h" >> >> #include "brw_context.h" >> -#include "intel_chipset.h" >> +#include "intel_batchbuffer.h" >> #include "intel_reg.h" >> #include "utils.h" >> >> /** >> + * Test if we can use MI_LOAD_REGISTER_MEM from an untrusted batchbuffer. >> + * >> + * Some combinations of hardware and kernel versions allow this feature, >> + * while others don't. Instead of trying to enumerate every case, just >> + * try and write a register and see if works. >> + */ > > We actually get noops instead of hangs in the not-supported case? > Sweet. > >> +static bool >> +can_do_pipelined_register_writes(struct brw_context *brw) >> +{ >> + /* We use SO_WRITE_OFFSET0 since you're supposed to write it (unlike the >> + * statistics registers), and we already reset it to zero before using >> it. >> + */ >> + const int reg = GEN7_SO_WRITE_OFFSET(0); >> + const int expected_value = 0x1337d0d0; >> + const int offset = 100; >> + >> + /* The register we picked only exists on Gen7+. */ >> + assert(brw->gen >= 7); >> + >> + uint32_t *data; >> + /* Set a value in a BO to a known quantity. The workaround BO already >> + * exists and doesn't contain anything important, so we may as well use >> it. >> + */ >> + drm_intel_bo_map(brw->batch.workaround_bo, false); > > You're writing, so that should be "true".
Oops. Right, thanks. >> + data = brw->batch.workaround_bo->virtual; >> + data[offset] = 0xffffffff; >> + drm_intel_bo_unmap(brw->batch.workaround_bo); >> + >> + /* Write the register. */ >> + BEGIN_BATCH(3); >> + OUT_BATCH(MI_LOAD_REGISTER_IMM | (3 - 2)); >> + OUT_BATCH(reg); >> + OUT_BATCH(expected_value); >> + ADVANCE_BATCH(); >> + >> + intel_batchbuffer_emit_mi_flush(brw); >> + >> + /* Save the register's value back to the buffer. */ >> + BEGIN_BATCH(3); >> + OUT_BATCH(MI_STORE_REGISTER_MEM | (3 - 2)); >> + OUT_BATCH(reg); >> + OUT_RELOC(brw->batch.workaround_bo, >> + I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, > > I thought we decided these were supposed to be _INSTRUCTION Definitely for Sandybridge, but this only works on Ivybridge. I didn't think it mattered there. But INSTRUCTION is fine, I'll use that for consistency. >> + offset * sizeof(uint32_t)); >> + ADVANCE_BATCH(); >> + >> + intel_batchbuffer_flush(brw); >> + >> + /* Check whether the value got written. */ >> + drm_intel_bo_map(brw->batch.workaround_bo, false); >> + bool success = data[offset] == expected_value; >> + drm_intel_bo_unmap(brw->batch.workaround_bo); >> + >> + return success; >> +} > > Other than that, Reviewed-by: Eric Anholt <e...@anholt.net> _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev