* Chia-I Wu <olv@lunarg.com>
*/
-#include "core/ilo_builder_3d.h" /* for gen6_3d_translate_pipe_prim() */
-#include "core/ilo_format.h"
#include "util/u_dual_blend.h"
#include "util/u_dynarray.h"
#include "util/u_framebuffer.h"
#include "util/u_upload_mgr.h"
#include "ilo_context.h"
+#include "ilo_format.h"
#include "ilo_resource.h"
#include "ilo_shader.h"
#include "ilo_state.h"
+/**
+ * Translate a pipe primitive type to the matching hardware primitive type.
+ */
+static enum gen_3dprim_type
+ilo_translate_draw_mode(unsigned mode)
+{
+ static const enum gen_3dprim_type prim_mapping[PIPE_PRIM_MAX] = {
+ [PIPE_PRIM_POINTS] = GEN6_3DPRIM_POINTLIST,
+ [PIPE_PRIM_LINES] = GEN6_3DPRIM_LINELIST,
+ [PIPE_PRIM_LINE_LOOP] = GEN6_3DPRIM_LINELOOP,
+ [PIPE_PRIM_LINE_STRIP] = GEN6_3DPRIM_LINESTRIP,
+ [PIPE_PRIM_TRIANGLES] = GEN6_3DPRIM_TRILIST,
+ [PIPE_PRIM_TRIANGLE_STRIP] = GEN6_3DPRIM_TRISTRIP,
+ [PIPE_PRIM_TRIANGLE_FAN] = GEN6_3DPRIM_TRIFAN,
+ [PIPE_PRIM_QUADS] = GEN6_3DPRIM_QUADLIST,
+ [PIPE_PRIM_QUAD_STRIP] = GEN6_3DPRIM_QUADSTRIP,
+ [PIPE_PRIM_POLYGON] = GEN6_3DPRIM_POLYGON,
+ [PIPE_PRIM_LINES_ADJACENCY] = GEN6_3DPRIM_LINELIST_ADJ,
+ [PIPE_PRIM_LINE_STRIP_ADJACENCY] = GEN6_3DPRIM_LINESTRIP_ADJ,
+ [PIPE_PRIM_TRIANGLES_ADJACENCY] = GEN6_3DPRIM_TRILIST_ADJ,
+ [PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY] = GEN6_3DPRIM_TRISTRIP_ADJ,
+ };
+
+ assert(prim_mapping[mode]);
+
+ return prim_mapping[mode];
+}
+
static enum gen_index_format
ilo_translate_index_size(unsigned index_size)
{
if (cbuf->cso[i].resource)
continue;
- u_upload_data(ilo->uploader, 0, cbuf->cso[i].info.size,
+ u_upload_data(ilo->uploader, 0, cbuf->cso[i].info.size, 16,
cbuf->cso[i].user_buffer, &offset, &cbuf->cso[i].resource);
- cbuf->cso[i].info.buf = ilo_buffer(cbuf->cso[i].resource);
+ cbuf->cso[i].info.vma = ilo_resource_get_vma(cbuf->cso[i].resource);
cbuf->cso[i].info.offset = offset;
memset(&cbuf->cso[i].surface, 0, sizeof(cbuf->cso[i].surface));
ilo_state_surface_init_for_buffer(&cbuf->cso[i].surface,
ilo->dev, &cbuf->cso[i].info);
- cbuf->cso[i].surface.bo = cbuf->cso[i].info.buf->bo;
ilo->state_vector.dirty |= ILO_DIRTY_CBUF;
}
static void
finalize_index_buffer(struct ilo_context *ilo)
{
+ const struct ilo_dev *dev = ilo->dev;
struct ilo_state_vector *vec = &ilo->state_vector;
const bool need_upload = (vec->draw->indexed &&
(vec->ib.state.user_buffer ||
vec->ib.state.offset % vec->ib.state.index_size));
struct pipe_resource *current_hw_res = NULL;
+ struct ilo_state_index_buffer_info info;
+ int64_t vertex_start_bias = 0;
if (!(vec->dirty & ILO_DIRTY_IB) && !need_upload)
return;
unsigned hw_offset;
if (vec->ib.state.user_buffer) {
- u_upload_data(ilo->uploader, 0, size,
+ u_upload_data(ilo->uploader, 0, size, 16,
vec->ib.state.user_buffer + offset,
&hw_offset, &vec->ib.hw_resource);
} else {
u_upload_buffer(ilo->uploader, 0,
- vec->ib.state.offset + offset, size, vec->ib.state.buffer,
+ vec->ib.state.offset + offset, size, 16, vec->ib.state.buffer,
&hw_offset, &vec->ib.hw_resource);
}
/* the HW offset should be aligned */
assert(hw_offset % vec->ib.state.index_size == 0);
- vec->ib.draw_start_offset = hw_offset / vec->ib.state.index_size;
+ vertex_start_bias = hw_offset / vec->ib.state.index_size;
/*
* INDEX[vec->draw->start] in the original buffer is INDEX[0] in the HW
* resource
*/
- vec->ib.draw_start_offset -= vec->draw->start;
+ vertex_start_bias -= vec->draw->start;
} else {
pipe_resource_reference(&vec->ib.hw_resource, vec->ib.state.buffer);
/* note that index size may be zero when the draw is not indexed */
- if (vec->draw->indexed) {
- vec->ib.draw_start_offset =
- vec->ib.state.offset / vec->ib.state.index_size;
- } else {
- vec->ib.draw_start_offset = 0;
- }
+ if (vec->draw->indexed)
+ vertex_start_bias = vec->ib.state.offset / vec->ib.state.index_size;
}
+ vec->draw_info.vertex_start += vertex_start_bias;
+
/* treat the IB as clean if the HW states do not change */
if (vec->ib.hw_resource == current_hw_res &&
vec->ib.hw_index_size == vec->ib.state.index_size)
vec->ib.hw_index_size = vec->ib.state.index_size;
pipe_resource_reference(¤t_hw_res, NULL);
+
+ memset(&info, 0, sizeof(info));
+ if (vec->ib.hw_resource) {
+ info.vma = ilo_resource_get_vma(vec->ib.hw_resource);
+ info.size = info.vma->vm_size;
+ info.format = ilo_translate_index_size(vec->ib.hw_index_size);
+ }
+
+ ilo_state_index_buffer_set_info(&vec->ib.ib, dev, &info);
}
static void
const struct ilo_dev *dev = ilo->dev;
struct ilo_state_vector *vec = &ilo->state_vector;
struct ilo_ve_state *ve = vec->ve;
- const enum gen_3dprim_type topology =
- gen6_3d_translate_pipe_prim(vec->draw->mode);
const bool last_element_edge_flag = (vec->vs &&
ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_INPUT_EDGEFLAG));
const bool prepend_vertexid = (vec->vs &&
ilo_translate_index_size(vec->ib.state.index_size) : GEN6_INDEX_DWORD;
/* check for non-orthogonal states */
- if (ve->vf_params.cv_topology != topology ||
+ if (ve->vf_params.cv_topology != vec->draw_info.topology ||
ve->vf_params.prepend_vertexid != prepend_vertexid ||
ve->vf_params.prepend_instanceid != prepend_instanceid ||
ve->vf_params.last_element_edge_flag != last_element_edge_flag ||
ve->vf_params.cv_index_format != index_format ||
ve->vf_params.cut_index_enable != vec->draw->primitive_restart ||
ve->vf_params.cut_index != vec->draw->restart_index) {
- ve->vf_params.cv_topology = topology;
+ ve->vf_params.cv_topology = vec->draw_info.topology;
ve->vf_params.prepend_vertexid = prepend_vertexid;
ve->vf_params.prepend_instanceid = prepend_instanceid;
ve->vf_params.last_element_edge_flag = last_element_edge_flag;
}
}
+static void
+finalize_vertex_buffers(struct ilo_context *ilo)
+{
+ const struct ilo_dev *dev = ilo->dev;
+ struct ilo_state_vector *vec = &ilo->state_vector;
+ struct ilo_state_vertex_buffer_info info;
+ unsigned i;
+
+ if (!(vec->dirty & (ILO_DIRTY_VE | ILO_DIRTY_VB)))
+ return;
+
+ memset(&info, 0, sizeof(info));
+
+ for (i = 0; i < vec->ve->vb_count; i++) {
+ const unsigned pipe_idx = vec->ve->vb_mapping[i];
+ const struct pipe_vertex_buffer *cso = &vec->vb.states[pipe_idx];
+
+ if (cso->buffer) {
+ info.vma = ilo_resource_get_vma(cso->buffer);
+ info.offset = cso->buffer_offset;
+ info.size = info.vma->vm_size - cso->buffer_offset;
+
+ info.stride = cso->stride;
+ } else {
+ memset(&info, 0, sizeof(info));
+ }
+
+ ilo_state_vertex_buffer_set_info(&vec->vb.vb[i], dev, &info);
+ }
+}
+
static void
finalize_urb(struct ilo_context *ilo)
{
{
ilo->state_vector.draw = draw;
+ ilo->state_vector.draw_info.topology = ilo_translate_draw_mode(draw->mode);
+ ilo->state_vector.draw_info.indexed = draw->indexed;
+ ilo->state_vector.draw_info.vertex_count = draw->count;
+ ilo->state_vector.draw_info.vertex_start = draw->start;
+ ilo->state_vector.draw_info.instance_count = draw->instance_count;
+ ilo->state_vector.draw_info.instance_start = draw->start_instance;
+ ilo->state_vector.draw_info.vertex_base = draw->index_bias;
+
finalize_blend(ilo);
finalize_shader_states(&ilo->state_vector);
finalize_constant_buffers(ilo);
finalize_index_buffer(ilo);
finalize_vertex_elements(ilo);
+ finalize_vertex_buffers(ilo);
finalize_urb(ilo);
finalize_rasterizer(ilo);
{
const struct ilo_dev *dev = ilo_context(pipe)->dev;
struct ilo_state_vf_element_info vf_elements[PIPE_MAX_ATTRIBS];
+ unsigned instance_divisors[PIPE_MAX_ATTRIBS];
struct ilo_state_vf_info vf_info;
struct ilo_ve_state *ve;
unsigned i;
*/
for (hw_idx = 0; hw_idx < ve->vb_count; hw_idx++) {
if (ve->vb_mapping[hw_idx] == elem->vertex_buffer_index &&
- ve->instance_divisors[hw_idx] == elem->instance_divisor)
+ instance_divisors[hw_idx] == elem->instance_divisor)
break;
}
hw_idx = ve->vb_count++;
ve->vb_mapping[hw_idx] = elem->vertex_buffer_index;
- ve->instance_divisors[hw_idx] = elem->instance_divisor;
+ instance_divisors[hw_idx] = elem->instance_divisor;
}
attr->buffer = hw_idx;
attr->format_size = util_format_get_blocksize(elem->src_format);
attr->component_count = util_format_get_nr_components(elem->src_format);
attr->is_integer = util_format_is_pure_integer(elem->src_format);
- attr->is_double = (util_format_is_float(elem->src_format) &&
- attr->format_size == attr->component_count * 8);
+
+ attr->instancing_enable = (elem->instance_divisor != 0);
+ attr->instancing_step_rate = elem->instance_divisor;
}
memset(&vf_info, 0, sizeof(vf_info));
cso->info.size = buf[i].buffer_size;
if (buf[i].buffer) {
- cso->info.buf = ilo_buffer(buf[i].buffer);
+ cso->info.vma = ilo_resource_get_vma(buf[i].buffer);
cso->info.offset = buf[i].buffer_offset;
memset(&cso->surface, 0, sizeof(cso->surface));
ilo_state_surface_init_for_buffer(&cso->surface, dev, &cso->info);
- cso->surface.bo = cso->info.buf->bo;
cso->user_buffer = NULL;
cbuf->enabled_mask |= 1 << (index + i);
} else if (buf[i].user_buffer) {
- cso->info.buf = NULL;
+ cso->info.vma = NULL;
/* buffer_offset does not apply for user buffer */
cso->user_buffer = buf[i].user_buffer;
cbuf->enabled_mask |= 1 << (index + i);
} else {
- cso->info.buf = NULL;
+ cso->info.vma = NULL;
cso->info.size = 0;
cso->user_buffer = NULL;
pipe_resource_reference(&cso->resource, NULL);
- cso->info.buf = NULL;
+ cso->info.vma = NULL;
cso->info.size = 0;
cso->user_buffer = NULL;
if (state->zsbuf) {
const struct ilo_surface_cso *cso =
(const struct ilo_surface_cso *) state->zsbuf;
+ const struct ilo_texture *tex = ilo_texture(cso->base.texture);
- fb->has_hiz = cso->u.zs.hiz_bo;
+ fb->has_hiz = cso->u.zs.hiz_vma;
fb->depth_offset_format =
- ilo_state_zs_get_depth_format(&cso->u.zs, dev);
+ ilo_format_translate_depth(dev, tex->image_format);
} else {
fb->has_hiz = false;
fb->depth_offset_format = GEN6_ZFORMAT_D32_FLOAT;
}
static void
-ilo_set_shader_resources(struct pipe_context *pipe,
- unsigned start, unsigned count,
- struct pipe_surface **surfaces)
+ilo_set_shader_images(struct pipe_context *pipe, unsigned shader,
+ unsigned start, unsigned count,
+ struct pipe_image_view *views)
{
+#if 0
struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
struct ilo_resource_state *dst = &vec->resource;
unsigned i;
}
vec->dirty |= ILO_DIRTY_RESOURCE;
+#endif
}
static void
unsigned buffer_offset,
unsigned buffer_size)
{
- struct pipe_stream_output_target *target;
+ const struct ilo_dev *dev = ilo_context(pipe)->dev;
+ struct ilo_stream_output_target *target;
+ struct ilo_state_sol_buffer_info info;
- target = MALLOC_STRUCT(pipe_stream_output_target);
+ target = CALLOC_STRUCT(ilo_stream_output_target);
assert(target);
- pipe_reference_init(&target->reference, 1);
- target->buffer = NULL;
- pipe_resource_reference(&target->buffer, res);
- target->context = pipe;
- target->buffer_offset = buffer_offset;
- target->buffer_size = buffer_size;
+ pipe_reference_init(&target->base.reference, 1);
+ pipe_resource_reference(&target->base.buffer, res);
+ target->base.context = pipe;
+ target->base.buffer_offset = buffer_offset;
+ target->base.buffer_size = buffer_size;
+
+ memset(&info, 0, sizeof(info));
+ info.vma = ilo_resource_get_vma(res);
+ info.offset = buffer_offset;
+ info.size = buffer_size;
- return target;
+ ilo_state_sol_buffer_init(&target->sb, dev, &info);
+
+ return &target->base;
}
static void
struct ilo_state_surface_buffer_info info;
memset(&info, 0, sizeof(info));
- info.buf = ilo_buffer(res);
+ info.vma = ilo_resource_get_vma(res);
+ info.offset = templ->u.buf.first_element * info.struct_size;
+ info.size = (templ->u.buf.last_element -
+ templ->u.buf.first_element + 1) * info.struct_size;
info.access = ILO_STATE_SURFACE_ACCESS_SAMPLER;
info.format = ilo_format_translate_color(dev, templ->format);
info.format_size = util_format_get_blocksize(templ->format);
info.struct_size = info.format_size;
info.readonly = true;
- info.offset = templ->u.buf.first_element * info.struct_size;
- info.size = (templ->u.buf.last_element -
- templ->u.buf.first_element + 1) * info.struct_size;
ilo_state_surface_init_for_buffer(&view->surface, dev, &info);
- view->surface.bo = info.buf->bo;
} else {
struct ilo_texture *tex = ilo_texture(res);
struct ilo_state_surface_image_info info;
}
memset(&info, 0, sizeof(info));
+
info.img = &tex->image;
+ info.level_base = templ->u.tex.first_level;
+ info.level_count = templ->u.tex.last_level -
+ templ->u.tex.first_level + 1;
+ info.slice_base = templ->u.tex.first_layer;
+ info.slice_count = templ->u.tex.last_layer -
+ templ->u.tex.first_layer + 1;
+ info.vma = &tex->vma;
info.access = ILO_STATE_SURFACE_ACCESS_SAMPLER;
+ info.type = tex->image.type;
if (templ->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT &&
- tex->image.separate_stencil) {
+ tex->separate_s8) {
info.format = ilo_format_translate_texture(dev,
PIPE_FORMAT_Z32_FLOAT);
} else {
info.format = ilo_format_translate_texture(dev, templ->format);
}
- info.is_cube_map = (tex->image.target == PIPE_TEXTURE_CUBE ||
- tex->image.target == PIPE_TEXTURE_CUBE_ARRAY);
info.is_array = util_resource_is_array_texture(&tex->base);
info.readonly = true;
- info.level_base = templ->u.tex.first_level;
- info.level_count = templ->u.tex.last_level -
- templ->u.tex.first_level + 1;
- info.slice_base = templ->u.tex.first_layer;
- info.slice_count = templ->u.tex.last_layer -
- templ->u.tex.first_layer + 1;
-
ilo_state_surface_init_for_image(&view->surface, dev, &info);
- view->surface.bo = info.img->bo;
}
return &view->base;
assert(tex->base.target != PIPE_BUFFER);
memset(&info, 0, sizeof(info));
+
info.img = &tex->image;
- info.access = ILO_STATE_SURFACE_ACCESS_DP_RENDER;
- info.format = ilo_format_translate_render(dev, templ->format);
- info.is_array = util_resource_is_array_texture(&tex->base);
info.level_base = templ->u.tex.level;
info.level_count = 1;
info.slice_base = templ->u.tex.first_layer;
info.slice_count = templ->u.tex.last_layer -
templ->u.tex.first_layer + 1;
+ info.vma = &tex->vma;
+ if (ilo_image_can_enable_aux(&tex->image, templ->u.tex.level))
+ info.aux_vma = &tex->aux_vma;
+
+ info.access = ILO_STATE_SURFACE_ACCESS_DP_RENDER;
+
+ info.type = (tex->image.type == GEN6_SURFTYPE_CUBE) ?
+ GEN6_SURFTYPE_2D : tex->image.type;
+
+ info.format = ilo_format_translate_render(dev, templ->format);
+ info.is_array = util_resource_is_array_texture(&tex->base);
+
ilo_state_surface_init_for_image(&surf->u.rt, dev, &info);
- surf->u.rt.bo = info.img->bo;
} else {
struct ilo_state_zs_info info;
memset(&info, 0, sizeof(info));
if (templ->format == PIPE_FORMAT_S8_UINT) {
+ info.s_vma = &tex->vma;
info.s_img = &tex->image;
} else {
+ info.z_vma = &tex->vma;
info.z_img = &tex->image;
- info.s_img = (tex->separate_s8) ? &tex->separate_s8->image : NULL;
- info.hiz_enable =
- ilo_image_can_enable_aux(&tex->image, templ->u.tex.level);
+ if (tex->separate_s8) {
+ info.s_vma = &tex->separate_s8->vma;
+ info.s_img = &tex->separate_s8->image;
+ }
+
+ if (ilo_image_can_enable_aux(&tex->image, templ->u.tex.level))
+ info.hiz_vma = &tex->aux_vma;
}
info.level = templ->u.tex.level;
info.slice_count = templ->u.tex.last_layer -
templ->u.tex.first_layer + 1;
- ilo_state_zs_init(&surf->u.zs, dev, &info);
+ info.type = (tex->image.type == GEN6_SURFTYPE_CUBE) ?
+ GEN6_SURFTYPE_2D : tex->image.type;
- if (info.z_img) {
- surf->u.zs.depth_bo = info.z_img->bo;
- if (info.hiz_enable)
- surf->u.zs.hiz_bo = info.z_img->aux.bo;
- }
+ info.format = ilo_format_translate_depth(dev, tex->image_format);
+ if (ilo_dev_gen(dev) == ILO_GEN(6) && !info.hiz_vma &&
+ tex->image_format == PIPE_FORMAT_Z24X8_UNORM)
+ info.format = GEN6_ZFORMAT_D24_UNORM_S8_UINT;
- if (info.s_img)
- surf->u.zs.stencil_bo = info.s_img->bo;
+ ilo_state_zs_init(&surf->u.zs, dev, &info);
}
return &surf->base;
ilo->base.set_scissor_states = ilo_set_scissor_states;
ilo->base.set_viewport_states = ilo_set_viewport_states;
ilo->base.set_sampler_views = ilo_set_sampler_views;
- ilo->base.set_shader_resources = ilo_set_shader_resources;
+ ilo->base.set_shader_images = ilo_set_shader_images;
ilo->base.set_vertex_buffers = ilo_set_vertex_buffers;
ilo->base.set_index_buffer = ilo_set_index_buffer;
ilo_state_ds_init_disabled(&vec->disabled_ds, dev);
ilo_state_gs_init_disabled(&vec->disabled_gs, dev);
+ ilo_state_sol_buffer_init_disabled(&vec->so.dummy_sb, dev);
+
ilo_state_surface_init_for_null(&vec->fb.null_rt, dev);
ilo_state_zs_init_for_null(&vec->fb.null_zs, dev);
ilo_state_vector_resource_renamed(struct ilo_state_vector *vec,
struct pipe_resource *res)
{
- struct intel_bo *bo = ilo_resource_get_bo(res);
uint32_t states = 0;
unsigned sh, i;
[PIPE_SHADER_GEOMETRY] = ILO_DIRTY_VIEW_GS,
[PIPE_SHADER_COMPUTE] = ILO_DIRTY_VIEW_CS,
};
- cso->surface.bo = bo;
states |= view_dirty_bits[sh];
break;
struct ilo_cbuf_cso *cbuf = &vec->cbuf[sh].cso[i];
if (cbuf->resource == res) {
- cbuf->surface.bo = bo;
states |= ILO_DIRTY_CBUF;
break;
}
(struct ilo_surface_cso *) vec->resource.states[i];
if (cso->base.texture == res) {
- cso->u.rt.bo = bo;
states |= ILO_DIRTY_RESOURCE;
break;
}
struct ilo_surface_cso *cso =
(struct ilo_surface_cso *) vec->fb.state.cbufs[i];
if (cso && cso->base.texture == res) {
- cso->u.rt.bo = bo;
states |= ILO_DIRTY_FB;
break;
}
}
- if (vec->fb.state.zsbuf && vec->fb.state.zsbuf->texture == res) {
- struct ilo_surface_cso *cso =
- (struct ilo_surface_cso *) vec->fb.state.zsbuf;
-
- cso->u.zs.depth_bo = bo;
-
+ if (vec->fb.state.zsbuf && vec->fb.state.zsbuf->texture == res)
states |= ILO_DIRTY_FB;
- }
}
for (i = 0; i < vec->cs_resource.count; i++) {
struct ilo_surface_cso *cso =
(struct ilo_surface_cso *) vec->cs_resource.states[i];
if (cso->base.texture == res) {
- cso->u.rt.bo = bo;
states |= ILO_DIRTY_CS_RESOURCE;
break;
}