mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 07:28:11 +02:00
i965: Enable ARB_transform_feedback2 on Gen7+ if register writes work.
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.
v2: Use I915_GEM_DOMAIN_INSTRUCTION for the register read, and also
correctly set the writeable flag when mapping (caught by Eric).
Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
parent
46d3c2bf4d
commit
129da5b1c8
1 changed files with 61 additions and 1 deletions
|
|
@ -28,10 +28,67 @@
|
|||
#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.
|
||||
*/
|
||||
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, true);
|
||||
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_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes potential list of extensions if ctx == NULL, or actually enables
|
||||
* extensions for a context.
|
||||
|
|
@ -171,6 +228,9 @@ intelInitExtensions(struct gl_context *ctx)
|
|||
if (brw->gen >= 7) {
|
||||
ctx->Extensions.ARB_texture_gather = true;
|
||||
ctx->Extensions.ARB_conservative_depth = true;
|
||||
if (can_do_pipelined_register_writes(brw)) {
|
||||
ctx->Extensions.ARB_transform_feedback2 = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->API == API_OPENGL_CORE)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue