/* 3DSTATE_URB_VS * 3DSTATE_URB_HS * 3DSTATE_URB_DS * 3DSTATE_URB_GS * * If the 3DSTATE_URB_VS is emitted, than the others must be also. * From the Ivybridge PRM, Volume 2 Part 1, section 1.7.1 3DSTATE_URB_VS: * * 3DSTATE_URB_HS, 3DSTATE_URB_DS, and 3DSTATE_URB_GS must also be * programmed in order for the programming of this state to be * valid. */ static void gen7_blorp_emit_urb_config(struct brw_context *brw) { unsigned urb_size = (brw->is_haswell && brw->gt == 3) ? 32 : 16; gen7_emit_push_constant_state(brw, urb_size / 2 /* vs_size */, 0 /* hs_size */, 0 /* ds_size */, 0 /* gs_size */, urb_size / 2 /* fs_size */); /* The minimum valid number of VS entries is 32. See 3DSTATE_URB_VS, Dword * 1.15:0 "VS Number of URB Entries". */ gen7_emit_urb_state(brw, 32 /* num_vs_entries */, 2 /* vs_size */, 2 /* vs_start */, 0 /* num_hs_entries */, 1 /* hs_size */, 2 /* hs_start */, 0 /* num_ds_entries */, 1 /* ds_size */, 2 /* ds_start */, 0 /* num_gs_entries */, 1 /* gs_size */, 2 /* gs_start */); }
/* 3DSTATE_URB_VS * 3DSTATE_URB_HS * 3DSTATE_URB_DS * 3DSTATE_URB_GS * * If the 3DSTATE_URB_VS is emitted, than the others must be also. * From the Ivybridge PRM, Volume 2 Part 1, section 1.7.1 3DSTATE_URB_VS: * * 3DSTATE_URB_HS, 3DSTATE_URB_DS, and 3DSTATE_URB_GS must also be * programmed in order for the programming of this state to be * valid. */ void gen7_blorp_emit_urb_config(struct brw_context *brw) { /* URB allocations must be done in 8k chunks. */ const unsigned chunk_size_bytes = 8192; const unsigned urb_size = (brw->gen >= 8 || (brw->is_haswell && brw->gt == 3)) ? 32 : 16; const unsigned push_constant_bytes = 1024 * urb_size; const unsigned push_constant_chunks = push_constant_bytes / chunk_size_bytes; const unsigned vs_size = 1; const unsigned vs_start = push_constant_chunks; const unsigned vs_chunks = DIV_ROUND_UP(brw->urb.min_vs_entries * vs_size * 64, chunk_size_bytes); if (gen7_blorp_skip_urb_config(brw)) return; brw->ctx.NewDriverState |= BRW_NEW_URB_SIZE; gen7_emit_push_constant_state(brw, urb_size / 2 /* vs_size */, 0 /* hs_size */, 0 /* ds_size */, 0 /* gs_size */, urb_size / 2 /* fs_size */); gen7_emit_urb_state(brw, brw->urb.min_vs_entries /* num_vs_entries */, vs_size, vs_start, 0 /* num_hs_entries */, 1 /* hs_size */, vs_start + vs_chunks /* hs_start */, 0 /* num_ds_entries */, 1 /* ds_size */, vs_start + vs_chunks /* ds_start */, 0 /* num_gs_entries */, 1 /* gs_size */, vs_start + vs_chunks /* gs_start */); }
/** * The following diagram shows how we partition the URB: * * 16kB or 32kB Rest of the URB space * __________-__________ _________________-_________________ * / \ / \ * +-------------------------------------------------------------+ * | VS/FS/GS Push | VS/GS URB | * | Constants | Entries | * +-------------------------------------------------------------+ * * Notably, push constants must be stored at the beginning of the URB * space, while entries can be stored anywhere. Ivybridge and Haswell * GT1/GT2 have a maximum constant buffer size of 16kB, while Haswell GT3 * doubles this (32kB). * * Ivybridge and Haswell GT1/GT2 allow push constants to be located (and * sized) in increments of 1kB. Haswell GT3 requires them to be located and * sized in increments of 2kB. * * Currently we split the constant buffer space evenly among whatever stages * are active. This is probably not ideal, but simple. * * Ivybridge GT1 and Haswell GT1 have 128kB of URB space. * Ivybridge GT2 and Haswell GT2 have 256kB of URB space. * Haswell GT3 has 512kB of URB space. * * See "Volume 2a: 3D Pipeline," section 1.8, "Volume 1b: Configurations", * and the documentation for 3DSTATE_PUSH_CONSTANT_ALLOC_xS. */ static void gen7_allocate_push_constants(struct brw_context *brw) { unsigned avail_size = 16; unsigned multiplier = (brw->gen >= 8 || (brw->is_haswell && brw->gt == 3)) ? 2 : 1; /* BRW_NEW_GEOMETRY_PROGRAM */ bool gs_present = brw->geometry_program; unsigned vs_size, gs_size; if (gs_present) { vs_size = avail_size / 3; avail_size -= vs_size; gs_size = avail_size / 2; avail_size -= gs_size; } else { vs_size = avail_size / 2; avail_size -= vs_size; gs_size = 0; } unsigned fs_size = avail_size; gen7_emit_push_constant_state(brw, multiplier * vs_size, multiplier * gs_size, multiplier * fs_size); /* From p115 of the Ivy Bridge PRM (3.2.1.4 3DSTATE_PUSH_CONSTANT_ALLOC_VS): * * Programming Restriction: * * The 3DSTATE_CONSTANT_VS must be reprogrammed prior to the next * 3DPRIMITIVE command after programming the * 3DSTATE_PUSH_CONSTANT_ALLOC_VS. * * Similar text exists for the other 3DSTATE_PUSH_CONSTANT_ALLOC_* * commands. */ brw->ctx.NewDriverState |= BRW_NEW_PUSH_CONSTANT_ALLOCATION; }