#include "genxml/gen_macros.h"
#include "genxml/genX_bits.h"
-#define MOCS_WB (2 << 1)
+#define MOCS_PTE (1 << 1)
+#define MOCS_WB (2 << 1)
+
+static uint32_t
+mocs(struct iris_bo *bo)
+{
+ return bo && bo->external ? MOCS_PTE : MOCS_WB;
+}
/**
* Statically assert that PIPE_* enums match the hardware packets.
* updated occasionally. See iris_binder.c for the details there.
*/
iris_emit_cmd(batch, GENX(STATE_BASE_ADDRESS), sba) {
- #if 0
- // XXX: MOCS is stupid for this.
- sba.GeneralStateMemoryObjectControlState = MOCS_WB;
- sba.StatelessDataPortAccessMemoryObjectControlState = MOCS_WB;
- sba.DynamicStateMemoryObjectControlState = MOCS_WB;
- sba.IndirectObjectMemoryObjectControlState = MOCS_WB;
- sba.InstructionMemoryObjectControlState = MOCS_WB;
- sba.BindlessSurfaceStateMemoryObjectControlState = MOCS_WB;
- #endif
+ sba.GeneralStateMOCS = MOCS_WB;
+ sba.StatelessDataPortAccessMOCS = MOCS_WB;
+ sba.DynamicStateMOCS = MOCS_WB;
+ sba.IndirectObjectMOCS = MOCS_WB;
+ sba.InstructionMOCS = MOCS_WB;
+ sba.BindlessSurfaceStateMOCS = MOCS_WB;
sba.GeneralStateBaseAddressModifyEnable = true;
sba.DynamicStateBaseAddressModifyEnable = true;
struct iris_depth_buffer_state depth_buffer;
uint32_t so_buffers[4 * GENX(3DSTATE_SO_BUFFER_length)];
- uint32_t streamout[4 * GENX(3DSTATE_STREAMOUT_length)];
};
/**
BRW_MAX_DRAW_BUFFERS * GENX(BLEND_STATE_ENTRY_length)];
bool alpha_to_coverage; /* for shader key */
+
+ /** Bitfield of whether blending is enabled for RT[i] - for aux resolves */
+ uint8_t blend_enables;
};
static enum pipe_blendfactor
struct iris_blend_state *cso = malloc(sizeof(struct iris_blend_state));
uint32_t *blend_entry = cso->blend_state + GENX(BLEND_STATE_length);
+ cso->blend_enables = 0;
+ STATIC_ASSERT(BRW_MAX_DRAW_BUFFERS <= 8);
+
cso->alpha_to_coverage = state->alpha_to_coverage;
bool indep_alpha_blend = false;
src_rgb != src_alpha || dst_rgb != dst_alpha)
indep_alpha_blend = true;
+ if (rt->blend_enable)
+ cso->blend_enables |= 1u << i;
+
iris_pack_state(GENX(BLEND_STATE_ENTRY), blend_entry, be) {
be.LogicOpEnable = state->logicop_enable;
be.LogicOpFunction = state->logicop_func;
iris_bind_blend_state(struct pipe_context *ctx, void *state)
{
struct iris_context *ice = (struct iris_context *) ctx;
- ice->state.cso_blend = state;
+ struct iris_blend_state *cso = state;
+
+ ice->state.cso_blend = cso;
+ ice->state.blend_enables = cso ? cso->blend_enables : 0;
+
ice->state.dirty |= IRIS_DIRTY_PS_BLEND;
ice->state.dirty |= IRIS_DIRTY_BLEND_STATE;
ice->state.dirty |= ice->state.dirty_for_nos[IRIS_NOS_BLEND];
.size_B = final_size,
.format = format,
.stride_B = cpp,
- .mocs = MOCS_WB);
+ .mocs = mocs(bo));
+}
+
+/**
+ * Allocate a SURFACE_STATE structure.
+ */
+static void *
+alloc_surface_states(struct u_upload_mgr *mgr,
+ struct iris_state_ref *ref)
+{
+ const unsigned surf_size = 4 * GENX(RENDER_SURFACE_STATE_length);
+
+ void *map = upload_state(mgr, ref, surf_size, 64);
+
+ ref->offset += iris_bo_offset_from_base_address(iris_resource_bo(ref->res));
+
+ return map;
+}
+
+static void
+fill_surface_state(struct isl_device *isl_dev,
+ void *map,
+ struct iris_resource *res,
+ struct isl_view *view)
+{
+ struct isl_surf_fill_state_info f = {
+ .surf = &res->surf,
+ .view = view,
+ .mocs = mocs(res->bo),
+ .address = res->bo->gtt_offset,
+ };
+
+ isl_surf_fill_state_s(isl_dev, map, &f);
}
/**
pipe_reference_init(&isv->base.reference, 1);
pipe_resource_reference(&isv->base.texture, tex);
- void *map = upload_state(ice->state.surface_uploader, &isv->surface_state,
- 4 * GENX(RENDER_SURFACE_STATE_length), 64);
+ void *map = alloc_surface_states(ice->state.surface_uploader,
+ &isv->surface_state);
if (!unlikely(map))
return NULL;
- struct iris_bo *state_bo = iris_resource_bo(isv->surface_state.res);
- isv->surface_state.offset += iris_bo_offset_from_base_address(state_bo);
-
if (util_format_is_depth_or_stencil(tmpl->format)) {
struct iris_resource *zres, *sres;
const struct util_format_description *desc =
isv->view.array_len =
tmpl->u.tex.last_layer - tmpl->u.tex.first_layer + 1;
- isl_surf_fill_state(&screen->isl_dev, map,
- .surf = &isv->res->surf, .view = &isv->view,
- .mocs = MOCS_WB,
- .address = isv->res->bo->gtt_offset);
- // .aux_surf =
- // .clear_color = clear_color,
+ fill_surface_state(&screen->isl_dev, map, isv->res, &isv->view);
} else {
fill_buffer_surface_state(&screen->isl_dev, isv->res->bo, map,
isv->view.format, tmpl->u.buf.offset,
return psurf;
- void *map = upload_state(ice->state.surface_uploader, &surf->surface_state,
- 4 * GENX(RENDER_SURFACE_STATE_length), 64);
+ void *map = alloc_surface_states(ice->state.surface_uploader,
+ &surf->surface_state);
if (!unlikely(map))
return NULL;
- struct iris_bo *state_bo = iris_resource_bo(surf->surface_state.res);
- surf->surface_state.offset += iris_bo_offset_from_base_address(state_bo);
-
- isl_surf_fill_state(&screen->isl_dev, map,
- .surf = &res->surf, .view = &surf->view,
- .mocs = MOCS_WB,
- .address = res->bo->gtt_offset);
- // .aux_surf =
- // .clear_color = clear_color,
+ fill_surface_state(&screen->isl_dev, map, res, &surf->view);
return psurf;
}
// XXX: these are not retained forever, use a separate uploader?
void *map =
- upload_state(ice->state.surface_uploader,
- &shs->image[start_slot + i].surface_state,
- 4 * GENX(RENDER_SURFACE_STATE_length), 64);
+ alloc_surface_states(ice->state.surface_uploader,
+ &shs->image[start_slot + i].surface_state);
if (!unlikely(map)) {
pipe_resource_reference(&shs->image[start_slot + i].res, NULL);
return;
}
- struct iris_bo *surf_state_bo =
- iris_resource_bo(shs->image[start_slot + i].surface_state.res);
- shs->image[start_slot + i].surface_state.offset +=
- iris_bo_offset_from_base_address(surf_state_bo);
-
isl_surf_usage_flags_t usage = ISL_SURF_USAGE_STORAGE_BIT;
enum isl_format isl_format =
iris_format_for_usage(devinfo, img->format, usage).fmt;
.usage = usage,
};
- isl_surf_fill_state(&screen->isl_dev, map,
- .surf = &res->surf, .view = &view,
- .mocs = MOCS_WB,
- .address = res->bo->gtt_offset);
- // .aux_surf =
- // .clear_color = clear_color,
+ fill_surface_state(&screen->isl_dev, map, res, &view);
} else {
fill_buffer_surface_state(&screen->isl_dev, res->bo, map,
isl_format, img->u.buf.offset,
.swizzle = ISL_SWIZZLE_IDENTITY,
};
- struct isl_depth_stencil_hiz_emit_info info = {
- .view = &view,
- .mocs = MOCS_WB,
- };
+ struct isl_depth_stencil_hiz_emit_info info = { .view = &view };
if (cso->zsbuf) {
iris_get_depth_stencil_resources(cso->zsbuf->texture, &zres,
info.depth_surf = &zres->surf;
info.depth_address = zres->bo->gtt_offset;
- info.hiz_usage = ISL_AUX_USAGE_NONE;
+ info.mocs = mocs(zres->bo);
view.format = zres->surf.format;
}
view.usage |= ISL_SURF_USAGE_STENCIL_BIT;
info.stencil_surf = &stencil_res->surf;
info.stencil_address = stencil_res->bo->gtt_offset;
- if (!zres)
+ if (!zres) {
view.format = stencil_res->surf.format;
+ info.mocs = mocs(stencil_res->bo);
+ }
}
}
res->bo->size - cbuf->data.offset),
.format = ISL_FORMAT_R32G32B32A32_FLOAT,
.stride_B = 1,
- .mocs = MOCS_WB)
+ .mocs = mocs(res->bo))
}
/**
res->bo->size - buffer->buffer_offset),
.format = ISL_FORMAT_RAW,
.stride_B = 1,
- .mocs = MOCS_WB);
+ .mocs = mocs(res->bo));
} else {
pipe_resource_reference(&shs->ssbo[start_slot + i], NULL);
pipe_resource_reference(&shs->ssbo_surface_state[start_slot + i].res,
iris_pack_state(GENX(VERTEX_BUFFER_STATE), state->state, vb) {
vb.VertexBufferIndex = start_slot + i;
- vb.MOCS = MOCS_WB;
vb.AddressModifyEnable = true;
vb.BufferPitch = buffer->stride;
if (res) {
vb.BufferSize = res->bo->size;
vb.BufferStartingAddress =
- ro_bo(NULL, res->bo->gtt_offset + buffer->buffer_offset);
+ ro_bo(NULL, res->bo->gtt_offset + (int) buffer->buffer_offset);
+ vb.MOCS = mocs(res->bo);
} else {
vb.NullVertexBuffer = true;
}
sob.SOBufferEnable = true;
sob.StreamOffsetWriteEnable = true;
sob.StreamOutputBufferOffsetAddressEnable = true;
- sob.MOCS = MOCS_WB; // XXX: MOCS
+ sob.MOCS = mocs(res->bo);
sob.SurfaceSize = MAX2(tgt->base.buffer_size / 4, 1) - 1;
/* XXX: this should be generated when putting programs in place */
- // XXX: raster->sprite_coord_enable
-
for (int fs_attr = 0; fs_attr < VARYING_SLOT_MAX; fs_attr++) {
const int input_index = wm_prog_data->urb_setup[fs_attr];
if (input_index < 0 || input_index >= 16)
iris_populate_fs_key(const struct iris_context *ice,
struct brw_wm_prog_key *key)
{
- /* XXX: dirty flags? */
const struct pipe_framebuffer_state *fb = &ice->state.framebuffer;
const struct iris_depth_stencil_alpha_state *zsa = ice->state.cso_zsa;
const struct iris_rasterizer_state *rast = ice->state.cso_rast;
key->coherent_fb_fetch = true;
- // XXX: uint64_t input_slots_valid; - for >16 inputs
-
// XXX: key->force_dual_color_blend for unigine
// XXX: respect hint for high_quality_derivatives:1;
}
pkt.Enable = true; \
\
if (prog_data->total_scratch) { \
- uint32_t scratch_addr = \
+ struct iris_bo *bo = \
iris_get_scratch_space(ice, prog_data->total_scratch, stage); \
+ uint32_t scratch_addr = bo->gtt_offset; \
pkt.PerThreadScratchSpace = ffs(prog_data->total_scratch) - 11; \
pkt.ScratchSpaceBasePointer = rw_bo(NULL, scratch_addr); \
}
KSP(shader) + brw_wm_prog_data_prog_offset(wm_prog_data, ps, 2);
if (prog_data->total_scratch) {
- uint32_t scratch_addr =
+ struct iris_bo *bo =
iris_get_scratch_space(ice, prog_data->total_scratch,
MESA_SHADER_FRAGMENT);
+ uint32_t scratch_addr = bo->gtt_offset;
ps.PerThreadScratchSpace = ffs(prog_data->total_scratch) - 11;
ps.ScratchSpaceBasePointer = rw_bo(NULL, scratch_addr);
}
{
struct iris_genx_state *genx = ice->state.genx;
- // XXX: whack IRIS_SHADER_DIRTY_BINDING_TABLE on new batch
-
const uint64_t clean = ~ice->state.dirty;
if (clean & IRIS_DIRTY_CC_VIEWPORT) {
for (int stage = 0; stage <= MESA_SHADER_FRAGMENT; stage++) {
if (clean & (IRIS_DIRTY_VS << stage)) {
struct iris_compiled_shader *shader = ice->shaders.prog[stage];
+
if (shader) {
struct iris_bo *bo = iris_resource_bo(shader->assembly.res);
iris_use_pinned_bo(batch, bo, false);
- }
- // XXX: scratch buffer
+ struct brw_stage_prog_data *prog_data = shader->prog_data;
+
+ if (prog_data->total_scratch > 0) {
+ struct iris_bo *bo =
+ iris_get_scratch_space(ice, prog_data->total_scratch, stage);
+ iris_use_pinned_bo(batch, bo, true);
+ }
+ }
}
}
struct iris_resource *zres, *sres;
iris_get_depth_stencil_resources(cso_fb->zsbuf->texture,
&zres, &sres);
- // XXX: might not be writable...
- if (zres)
- iris_use_pinned_bo(batch, zres->bo, true);
- if (sres)
- iris_use_pinned_bo(batch, sres->bo, true);
+ if (zres) {
+ iris_use_pinned_bo(batch, zres->bo,
+ ice->state.depth_writes_enabled);
+ }
+ if (sres) {
+ iris_use_pinned_bo(batch, sres->bo,
+ ice->state.stencil_writes_enabled);
+ }
}
}
if (clean & IRIS_DIRTY_CS) {
struct iris_compiled_shader *shader = ice->shaders.prog[stage];
+
if (shader) {
struct iris_bo *bo = iris_resource_bo(shader->assembly.res);
iris_use_pinned_bo(batch, bo, false);
- }
- // XXX: scratch buffer
+ struct brw_stage_prog_data *prog_data = shader->prog_data;
+
+ if (prog_data->total_scratch > 0) {
+ struct iris_bo *bo =
+ iris_get_scratch_space(ice, prog_data->total_scratch, stage);
+ iris_use_pinned_bo(batch, bo, true);
+ }
+ }
}
}
flush_for_state_base_change(batch);
iris_emit_cmd(batch, GENX(STATE_BASE_ADDRESS), sba) {
- // XXX: sba.SurfaceStateMemoryObjectControlState = MOCS_WB;
+ sba.SurfaceStateMOCS = MOCS_WB;
sba.SurfaceStateBaseAddressModifyEnable = true;
sba.SurfaceStateBaseAddress = ro_bo(binder->bo, 0);
}
}
}
- /* XXX: L3 State */
-
- // XXX: this is only flagged at setup, we assume a static configuration
if (dirty & IRIS_DIRTY_URB) {
iris_upload_urb_config(ice, batch);
}
}
- /* XXX: FS program updates needs to flag IRIS_DIRTY_WM */
if (dirty & IRIS_DIRTY_WM) {
struct iris_rasterizer_state *cso = ice->state.cso_rast;
uint32_t dynamic_wm[GENX(3DSTATE_WM_length)];
struct iris_resource *zres, *sres;
iris_get_depth_stencil_resources(cso_fb->zsbuf->texture,
&zres, &sres);
- // XXX: might not be writable...
- if (zres)
- iris_use_pinned_bo(batch, zres->bo, true);
- if (sres)
- iris_use_pinned_bo(batch, sres->bo, true);
+ if (zres) {
+ iris_use_pinned_bo(batch, zres->bo,
+ ice->state.depth_writes_enabled);
+ }
+
+ if (sres) {
+ iris_use_pinned_bo(batch, sres->bo,
+ ice->state.stencil_writes_enabled);
+ }
}
}
iris_emit_cmd(batch, GENX(3DSTATE_INDEX_BUFFER), ib) {
ib.IndexFormat = draw->index_size >> 1;
- ib.MOCS = MOCS_WB;
+ ib.MOCS = mocs(bo);
ib.BufferSize = bo->size;
ib.BufferStartingAddress = ro_bo(bo, offset);
}
struct brw_stage_prog_data *prog_data = shader->prog_data;
struct brw_cs_prog_data *cs_prog_data = (void *) prog_data;
+ /* Always pin the binder. If we're emitting new binding table pointers,
+ * we need it. If not, we're probably inheriting old tables via the
+ * context, and need it anyway. Since true zero-bindings cases are
+ * practically non-existent, just pin it and avoid last_res tracking.
+ */
+ iris_use_pinned_bo(batch, ice->state.binder.bo, false);
+
if ((dirty & IRIS_DIRTY_CONSTANTS_CS) && shs->cbuf0_needs_upload)
upload_uniforms(ice, MESA_SHADER_COMPUTE);
iris_emit_cmd(batch, GENX(MEDIA_VFE_STATE), vfe) {
if (prog_data->total_scratch) {
- uint32_t scratch_addr =
+ struct iris_bo *bo =
iris_get_scratch_space(ice, prog_data->total_scratch,
MESA_SHADER_COMPUTE);
vfe.PerThreadScratchSpace = ffs(prog_data->total_scratch) - 11;
- vfe.ScratchSpaceBasePointer = rw_bo(NULL, scratch_addr);
+ vfe.ScratchSpaceBasePointer = rw_bo(bo, 0);
}
vfe.MaximumNumberofThreads =