Across the board of the various generations, the intial few atoms in
all of the atom lists are basically the same, (performing uploads for
the various programs). The only difference is that prior to gen6
there's an ff_gs upload in place of the later gs upload.
In this commit, instead of using the atom lists for this program state
upload, we add a new function brw_upload_programs that calls into the
per-stage upload functions which in turn check dirty bits and return
immediately if nothing needs to be done.
This commit is intended to have no functional change. The motivation
is that future code, (such as the shader cache), wants to have a
single function within which to perform various operations before and
after program upload, (with some local variables holding state across
the upload).
It may be worth looking at whether some of the other functionality
currently handled via atoms might also be more cleanly handled in a
similar fashion.
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
/* Calculate interpolants for triangle and line rasterization.
*/
/* Calculate interpolants for triangle and line rasterization.
*/
brw_upload_ff_gs_prog(struct brw_context *brw)
{
struct brw_ff_gs_prog_key key;
brw_upload_ff_gs_prog(struct brw_context *brw)
{
struct brw_ff_gs_prog_key key;
+
+ if (!brw_state_dirty(brw,
+ _NEW_LIGHT,
+ BRW_NEW_PRIMITIVE |
+ BRW_NEW_TRANSFORM_FEEDBACK |
+ BRW_NEW_VS_PROG_DATA))
+ return;
+
/* Populate the key:
*/
populate_key(brw, &key);
/* Populate the key:
*/
populate_key(brw, &key);
{
brw_upload_ff_gs_prog(brw);
}
{
brw_upload_ff_gs_prog(brw);
}
-
-const struct brw_tracked_state brw_ff_gs_prog = {
- .dirty = {
- .mesa = _NEW_LIGHT,
- .brw = BRW_NEW_PRIMITIVE |
- BRW_NEW_TRANSFORM_FEEDBACK |
- BRW_NEW_VS_PROG_DATA,
- },
- .emit = brw_upload_ff_gs_prog
-};
unsigned num_verts, bool check_edge_flag);
void gen6_brw_upload_ff_gs_prog(struct brw_context *brw);
unsigned num_verts, bool check_edge_flag);
void gen6_brw_upload_ff_gs_prog(struct brw_context *brw);
+void
+brw_upload_ff_gs_prog(struct brw_context *brw);
+
brw_upload_gs_prog(struct brw_context *brw)
{
struct gl_context *ctx = &brw->ctx;
brw_upload_gs_prog(struct brw_context *brw)
{
struct gl_context *ctx = &brw->ctx;
struct brw_geometry_program *gp =
(struct brw_geometry_program *) brw->geometry_program;
struct brw_geometry_program *gp =
(struct brw_geometry_program *) brw->geometry_program;
+ if (!brw_state_dirty(brw,
+ _NEW_TEXTURE,
+ BRW_NEW_GEOMETRY_PROGRAM |
+ BRW_NEW_TRANSFORM_FEEDBACK |
+ BRW_NEW_VUE_MAP_VS))
+ return;
+
if (gp == NULL) {
/* No geometry shader. Vertex data just passes straight through. */
if (brw->state.dirty.brw & BRW_NEW_VUE_MAP_VS) {
if (gp == NULL) {
/* No geometry shader. Vertex data just passes straight through. */
if (brw->state.dirty.brw & BRW_NEW_VUE_MAP_VS) {
-
-const struct brw_tracked_state brw_gs_prog = {
- .dirty = {
- .mesa = _NEW_TEXTURE,
- .brw = BRW_NEW_GEOMETRY_PROGRAM |
- BRW_NEW_TRANSFORM_FEEDBACK |
- BRW_NEW_VUE_MAP_VS,
- },
- .emit = brw_upload_gs_prog
-};
-
-
bool
brw_gs_precompile(struct gl_context *ctx,
struct gl_shader_program *shader_prog,
bool
brw_gs_precompile(struct gl_context *ctx,
struct gl_shader_program *shader_prog,
+#include "brw_context.h"
+
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
extern "C" {
#endif
bool brw_gs_prog_data_compare(const void *a, const void *b);
bool brw_gs_prog_data_compare(const void *a, const void *b);
+void
+brw_upload_gs_prog(struct brw_context *brw);
+
#ifdef __cplusplus
} /* extern "C" */
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
extern const struct brw_tracked_state gen8_vf_topology;
extern const struct brw_tracked_state gen8_vs_state;
extern const struct brw_tracked_state gen8_vf_topology;
extern const struct brw_tracked_state gen8_vs_state;
+static inline bool
+brw_state_dirty(struct brw_context *brw, GLuint mesa_flags, uint64_t brw_flags)
+{
+ return ((brw->state.dirty.mesa & mesa_flags) |
+ (brw->state.dirty.brw & brw_flags)) != 0;
+}
+
/* brw_misc_state.c */
void brw_upload_invariant_state(struct brw_context *brw);
uint32_t
/* brw_misc_state.c */
void brw_upload_invariant_state(struct brw_context *brw);
uint32_t
#include "drivers/common/meta.h"
#include "intel_batchbuffer.h"
#include "intel_buffers.h"
#include "drivers/common/meta.h"
#include "intel_batchbuffer.h"
#include "intel_buffers.h"
+#include "brw_vs.h"
+#include "brw_ff_gs.h"
+#include "brw_gs.h"
+#include "brw_wm.h"
static const struct brw_tracked_state *gen4_atoms[] =
{
static const struct brw_tracked_state *gen4_atoms[] =
{
- &brw_vs_prog, /* must do before GS prog, state base address. */
- &brw_ff_gs_prog, /* must do before state base address */
-
&brw_interpolation_map,
&brw_clip_prog, /* must do before state base address */
&brw_sf_prog, /* must do before state base address */
&brw_interpolation_map,
&brw_clip_prog, /* must do before state base address */
&brw_sf_prog, /* must do before state base address */
- &brw_wm_prog, /* must do before state base address */
/* Once all the programs are done, we know how large urb entry
* sizes need to be and can decide if we need to change the urb
/* Once all the programs are done, we know how large urb entry
* sizes need to be and can decide if we need to change the urb
static const struct brw_tracked_state *gen6_atoms[] =
{
static const struct brw_tracked_state *gen6_atoms[] =
{
- &brw_vs_prog, /* must do before state base address */
- &brw_gs_prog, /* must do before state base address */
- &brw_wm_prog, /* must do before state base address */
-
&gen6_clip_vp,
&gen6_sf_vp,
&gen6_clip_vp,
&gen6_sf_vp,
static const struct brw_tracked_state *gen7_atoms[] =
{
static const struct brw_tracked_state *gen7_atoms[] =
{
- &brw_vs_prog,
- &brw_gs_prog,
- &brw_wm_prog,
-
/* Command packets: */
/* must do before binding table pointers, cc state ptrs */
/* Command packets: */
/* must do before binding table pointers, cc state ptrs */
static const struct brw_tracked_state *gen8_atoms[] =
{
static const struct brw_tracked_state *gen8_atoms[] =
{
- &brw_vs_prog,
- &brw_gs_prog,
- &brw_wm_prog,
-
/* Command packets: */
&gen8_state_base_address,
/* Command packets: */
&gen8_state_base_address,
+static void
+brw_upload_programs(struct brw_context *brw)
+{
+ brw_upload_vs_prog(brw);
+
+ if (brw->gen < 6)
+ brw_upload_ff_gs_prog(brw);
+ else
+ brw_upload_gs_prog(brw);
+
+ brw_upload_wm_prog(brw);
+}
+
/***********************************************************************
* Emit all state:
*/
/***********************************************************************
* Emit all state:
*/
if (brw->gen == 6)
intel_emit_post_sync_nonzero_flush(brw);
if (brw->gen == 6)
intel_emit_post_sync_nonzero_flush(brw);
+ brw_upload_programs(brw);
+
if (unlikely(INTEL_DEBUG)) {
/* Debug version which enforces various sanity checks on the
* state flags which are generated and checked to help ensure
if (unlikely(INTEL_DEBUG)) {
/* Debug version which enforces various sanity checks on the
* state flags which are generated and checked to help ensure
-
-static void brw_upload_vs_prog(struct brw_context *brw)
+void
+brw_upload_vs_prog(struct brw_context *brw)
{
struct gl_context *ctx = &brw->ctx;
struct brw_vs_prog_key key;
{
struct gl_context *ctx = &brw->ctx;
struct brw_vs_prog_key key;
struct gl_program *prog = (struct gl_program *) brw->vertex_program;
int i;
struct gl_program *prog = (struct gl_program *) brw->vertex_program;
int i;
+ if (!brw_state_dirty(brw,
+ _NEW_BUFFERS |
+ _NEW_LIGHT |
+ _NEW_POINT |
+ _NEW_POLYGON |
+ _NEW_TEXTURE |
+ _NEW_TRANSFORM,
+ BRW_NEW_VERTEX_PROGRAM |
+ BRW_NEW_VS_ATTRIB_WORKAROUNDS))
+ return;
+
memset(&key, 0, sizeof(key));
/* Just upload the program verbatim for now. Always send it all
memset(&key, 0, sizeof(key));
/* Just upload the program verbatim for now. Always send it all
-/* See brw_vs.c:
- */
-const struct brw_tracked_state brw_vs_prog = {
- .dirty = {
- .mesa = _NEW_BUFFERS |
- _NEW_LIGHT |
- _NEW_POINT |
- _NEW_POLYGON |
- _NEW_TEXTURE |
- _NEW_TRANSFORM,
- .brw = BRW_NEW_VERTEX_PROGRAM |
- BRW_NEW_VS_ATTRIB_WORKAROUNDS,
- },
- .emit = brw_upload_vs_prog
-};
-
bool
brw_vs_precompile(struct gl_context *ctx,
struct gl_shader_program *shader_prog,
bool
brw_vs_precompile(struct gl_context *ctx,
struct gl_shader_program *shader_prog,
const struct brw_vs_prog_key *key);
bool brw_vs_prog_data_compare(const void *a, const void *b);
const struct brw_vs_prog_key *key);
bool brw_vs_prog_data_compare(const void *a, const void *b);
+void
+brw_upload_vs_prog(struct brw_context *brw);
+
#ifdef __cplusplus
} /* extern "C" */
#ifdef __cplusplus
} /* extern "C" */
key->program_string_id = fp->id;
}
key->program_string_id = fp->id;
}
brw_upload_wm_prog(struct brw_context *brw)
{
struct gl_context *ctx = &brw->ctx;
brw_upload_wm_prog(struct brw_context *brw)
{
struct gl_context *ctx = &brw->ctx;
struct brw_fragment_program *fp = (struct brw_fragment_program *)
brw->fragment_program;
struct brw_fragment_program *fp = (struct brw_fragment_program *)
brw->fragment_program;
+ if (!brw_state_dirty(brw,
+ _NEW_BUFFERS |
+ _NEW_COLOR |
+ _NEW_DEPTH |
+ _NEW_FRAG_CLAMP |
+ _NEW_HINT |
+ _NEW_LIGHT |
+ _NEW_LINE |
+ _NEW_MULTISAMPLE |
+ _NEW_POLYGON |
+ _NEW_STENCIL |
+ _NEW_TEXTURE,
+ BRW_NEW_FRAGMENT_PROGRAM |
+ BRW_NEW_REDUCED_PRIMITIVE |
+ BRW_NEW_STATS_WM |
+ BRW_NEW_VUE_MAP_GEOM_OUT))
+ return;
+
brw_wm_populate_key(brw, &key);
if (!brw_search_cache(&brw->cache, BRW_CACHE_FS_PROG,
brw_wm_populate_key(brw, &key);
if (!brw_search_cache(&brw->cache, BRW_CACHE_FS_PROG,
}
brw->wm.base.prog_data = &brw->wm.prog_data->base;
}
}
brw->wm.base.prog_data = &brw->wm.prog_data->base;
}
-
-
-const struct brw_tracked_state brw_wm_prog = {
- .dirty = {
- .mesa = _NEW_BUFFERS |
- _NEW_COLOR |
- _NEW_DEPTH |
- _NEW_FRAG_CLAMP |
- _NEW_HINT |
- _NEW_LIGHT |
- _NEW_LINE |
- _NEW_MULTISAMPLE |
- _NEW_POLYGON |
- _NEW_STENCIL |
- _NEW_TEXTURE,
- .brw = BRW_NEW_FRAGMENT_PROGRAM |
- BRW_NEW_REDUCED_PRIMITIVE |
- BRW_NEW_STATS_WM |
- BRW_NEW_VUE_MAP_GEOM_OUT,
- },
- .emit = brw_upload_wm_prog
-};
-
const struct brw_wm_prog_key *key);
bool brw_wm_prog_data_compare(const void *a, const void *b);
const struct brw_wm_prog_key *key);
bool brw_wm_prog_data_compare(const void *a, const void *b);
+void
+brw_upload_wm_prog(struct brw_context *brw);
+