mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-04 22:49:13 +02:00
genX/pipeline: Break emit_vertex_input out into common code
It's mostly the same and contains some non-trivial logic, so it really should be shared. Also, we're about to make some modifications here that we would really like to share.
This commit is contained in:
parent
fe6ccb6031
commit
da75492879
3 changed files with 107 additions and 156 deletions
|
|
@ -34,85 +34,6 @@
|
|||
|
||||
#include "genX_pipeline_util.h"
|
||||
|
||||
static void
|
||||
emit_vertex_input(struct anv_pipeline *pipeline,
|
||||
const VkPipelineVertexInputStateCreateInfo *info,
|
||||
const struct anv_graphics_pipeline_create_info *extra)
|
||||
{
|
||||
uint32_t elements;
|
||||
if (extra && extra->disable_vs) {
|
||||
/* If the VS is disabled, just assume the user knows what they're
|
||||
* doing and apply the layout blindly. This can only come from
|
||||
* meta, so this *should* be safe.
|
||||
*/
|
||||
elements = 0;
|
||||
for (uint32_t i = 0; i < info->vertexAttributeDescriptionCount; i++)
|
||||
elements |= (1 << info->pVertexAttributeDescriptions[i].location);
|
||||
} else {
|
||||
/* Pull inputs_read out of the VS prog data */
|
||||
uint64_t inputs_read = pipeline->vs_prog_data.inputs_read;
|
||||
assert((inputs_read & ((1 << VERT_ATTRIB_GENERIC0) - 1)) == 0);
|
||||
elements = inputs_read >> VERT_ATTRIB_GENERIC0;
|
||||
}
|
||||
|
||||
uint32_t vb_count = __builtin_popcount(elements);
|
||||
|
||||
if (pipeline->vs_prog_data.uses_vertexid ||
|
||||
pipeline->vs_prog_data.uses_instanceid)
|
||||
vb_count++;
|
||||
|
||||
if (vb_count == 0)
|
||||
return;
|
||||
|
||||
const uint32_t num_dwords = 1 + vb_count * 2;
|
||||
|
||||
uint32_t *p = anv_batch_emitn(&pipeline->batch, num_dwords,
|
||||
GEN7_3DSTATE_VERTEX_ELEMENTS);
|
||||
memset(p + 1, 0, (num_dwords - 1) * 4);
|
||||
|
||||
for (uint32_t i = 0; i < info->vertexAttributeDescriptionCount; i++) {
|
||||
const VkVertexInputAttributeDescription *desc =
|
||||
&info->pVertexAttributeDescriptions[i];
|
||||
enum isl_format format = anv_get_isl_format(desc->format,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
VK_IMAGE_TILING_LINEAR);
|
||||
|
||||
assert(desc->binding < 32);
|
||||
|
||||
if ((elements & (1 << desc->location)) == 0)
|
||||
continue; /* Binding unused */
|
||||
|
||||
uint32_t slot = __builtin_popcount(elements & ((1 << desc->location) - 1));
|
||||
|
||||
struct GEN7_VERTEX_ELEMENT_STATE element = {
|
||||
.VertexBufferIndex = desc->binding,
|
||||
.Valid = true,
|
||||
.SourceElementFormat = format,
|
||||
.EdgeFlagEnable = false,
|
||||
.SourceElementOffset = desc->offset,
|
||||
.Component0Control = vertex_element_comp_control(format, 0),
|
||||
.Component1Control = vertex_element_comp_control(format, 1),
|
||||
.Component2Control = vertex_element_comp_control(format, 2),
|
||||
.Component3Control = vertex_element_comp_control(format, 3),
|
||||
};
|
||||
GEN7_VERTEX_ELEMENT_STATE_pack(NULL, &p[1 + slot * 2], &element);
|
||||
}
|
||||
|
||||
if (pipeline->vs_prog_data.uses_vertexid ||
|
||||
pipeline->vs_prog_data.uses_instanceid) {
|
||||
struct GEN7_VERTEX_ELEMENT_STATE element = {
|
||||
.Valid = true,
|
||||
/* FIXME: Do we need to provide the base vertex as component 0 here
|
||||
* to support the correct base vertex ID? */
|
||||
.Component0Control = VFCOMP_STORE_0,
|
||||
.Component1Control = VFCOMP_STORE_0,
|
||||
.Component2Control = VFCOMP_STORE_VID,
|
||||
.Component3Control = VFCOMP_STORE_IID
|
||||
};
|
||||
GEN7_VERTEX_ELEMENT_STATE_pack(NULL, &p[1 + (vb_count - 1) * 2], &element);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gen7_emit_rs_state(struct anv_pipeline *pipeline,
|
||||
const VkPipelineRasterizationStateCreateInfo *info,
|
||||
|
|
|
|||
|
|
@ -34,83 +34,6 @@
|
|||
|
||||
#include "genX_pipeline_util.h"
|
||||
|
||||
static void
|
||||
emit_vertex_input(struct anv_pipeline *pipeline,
|
||||
const VkPipelineVertexInputStateCreateInfo *info,
|
||||
const struct anv_graphics_pipeline_create_info *extra)
|
||||
{
|
||||
static_assert(ANV_GEN >= 8, "should be compiling this for gen < 8");
|
||||
|
||||
uint32_t elements;
|
||||
if (extra && extra->disable_vs) {
|
||||
/* If the VS is disabled, just assume the user knows what they're
|
||||
* doing and apply the layout blindly. This can only come from
|
||||
* meta, so this *should* be safe.
|
||||
*/
|
||||
elements = 0;
|
||||
for (uint32_t i = 0; i < info->vertexAttributeDescriptionCount; i++)
|
||||
elements |= (1 << info->pVertexAttributeDescriptions[i].location);
|
||||
} else {
|
||||
/* Pull inputs_read out of the VS prog data */
|
||||
uint64_t inputs_read = pipeline->vs_prog_data.inputs_read;
|
||||
assert((inputs_read & ((1 << VERT_ATTRIB_GENERIC0) - 1)) == 0);
|
||||
elements = inputs_read >> VERT_ATTRIB_GENERIC0;
|
||||
}
|
||||
|
||||
const uint32_t num_dwords = 1 + __builtin_popcount(elements) * 2;
|
||||
|
||||
uint32_t *p;
|
||||
if (elements != 0) {
|
||||
p = anv_batch_emitn(&pipeline->batch, num_dwords,
|
||||
GENX(3DSTATE_VERTEX_ELEMENTS));
|
||||
memset(p + 1, 0, (num_dwords - 1) * 4);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < info->vertexAttributeDescriptionCount; i++) {
|
||||
const VkVertexInputAttributeDescription *desc =
|
||||
&info->pVertexAttributeDescriptions[i];
|
||||
enum isl_format format = anv_get_isl_format(desc->format,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
VK_IMAGE_TILING_LINEAR);
|
||||
|
||||
assert(desc->binding < 32);
|
||||
|
||||
if ((elements & (1 << desc->location)) == 0)
|
||||
continue; /* Binding unused */
|
||||
|
||||
uint32_t slot = __builtin_popcount(elements & ((1 << desc->location) - 1));
|
||||
|
||||
struct GENX(VERTEX_ELEMENT_STATE) element = {
|
||||
.VertexBufferIndex = desc->binding,
|
||||
.Valid = true,
|
||||
.SourceElementFormat = format,
|
||||
.EdgeFlagEnable = false,
|
||||
.SourceElementOffset = desc->offset,
|
||||
.Component0Control = vertex_element_comp_control(format, 0),
|
||||
.Component1Control = vertex_element_comp_control(format, 1),
|
||||
.Component2Control = vertex_element_comp_control(format, 2),
|
||||
.Component3Control = vertex_element_comp_control(format, 3),
|
||||
};
|
||||
GENX(VERTEX_ELEMENT_STATE_pack)(NULL, &p[1 + slot * 2], &element);
|
||||
|
||||
anv_batch_emit(&pipeline->batch, GENX(3DSTATE_VF_INSTANCING),
|
||||
.InstancingEnable = pipeline->instancing_enable[desc->binding],
|
||||
.VertexElementIndex = slot,
|
||||
/* Vulkan so far doesn't have an instance divisor, so
|
||||
* this is always 1 (ignored if not instancing). */
|
||||
.InstanceDataStepRate = 1);
|
||||
}
|
||||
|
||||
const uint32_t id_slot = __builtin_popcount(elements);
|
||||
anv_batch_emit(&pipeline->batch, GENX(3DSTATE_VF_SGVS),
|
||||
.VertexIDEnable = pipeline->vs_prog_data.uses_vertexid,
|
||||
.VertexIDComponentNumber = 2,
|
||||
.VertexIDElementOffset = id_slot,
|
||||
.InstanceIDEnable = pipeline->vs_prog_data.uses_instanceid,
|
||||
.InstanceIDComponentNumber = 3,
|
||||
.InstanceIDElementOffset = id_slot);
|
||||
}
|
||||
|
||||
static void
|
||||
emit_ia_state(struct anv_pipeline *pipeline,
|
||||
const VkPipelineInputAssemblyStateCreateInfo *info,
|
||||
|
|
|
|||
|
|
@ -47,6 +47,113 @@ vertex_element_comp_control(enum isl_format format, unsigned comp)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
emit_vertex_input(struct anv_pipeline *pipeline,
|
||||
const VkPipelineVertexInputStateCreateInfo *info,
|
||||
const struct anv_graphics_pipeline_create_info *extra)
|
||||
{
|
||||
uint32_t elements;
|
||||
if (extra && extra->disable_vs) {
|
||||
/* If the VS is disabled, just assume the user knows what they're
|
||||
* doing and apply the layout blindly. This can only come from
|
||||
* meta, so this *should* be safe.
|
||||
*/
|
||||
elements = 0;
|
||||
for (uint32_t i = 0; i < info->vertexAttributeDescriptionCount; i++)
|
||||
elements |= (1 << info->pVertexAttributeDescriptions[i].location);
|
||||
} else {
|
||||
/* Pull inputs_read out of the VS prog data */
|
||||
uint64_t inputs_read = pipeline->vs_prog_data.inputs_read;
|
||||
assert((inputs_read & ((1 << VERT_ATTRIB_GENERIC0) - 1)) == 0);
|
||||
elements = inputs_read >> VERT_ATTRIB_GENERIC0;
|
||||
}
|
||||
|
||||
uint32_t elem_count = __builtin_popcount(elements);
|
||||
|
||||
#if ANV_GEN <= 7
|
||||
/* On Haswell and prior, vertex and instance id are created by using the
|
||||
* ComponentControl fields, so we need an element for any of them.
|
||||
*/
|
||||
if (pipeline->vs_prog_data.uses_vertexid ||
|
||||
pipeline->vs_prog_data.uses_instanceid)
|
||||
elem_count++;
|
||||
#endif
|
||||
|
||||
uint32_t *p;
|
||||
if (elem_count > 0) {
|
||||
const uint32_t num_dwords = 1 + elem_count * 2;
|
||||
p = anv_batch_emitn(&pipeline->batch, num_dwords,
|
||||
GENX(3DSTATE_VERTEX_ELEMENTS));
|
||||
memset(p + 1, 0, (num_dwords - 1) * 4);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < info->vertexAttributeDescriptionCount; i++) {
|
||||
const VkVertexInputAttributeDescription *desc =
|
||||
&info->pVertexAttributeDescriptions[i];
|
||||
enum isl_format format = anv_get_isl_format(desc->format,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
VK_IMAGE_TILING_LINEAR);
|
||||
|
||||
assert(desc->binding < 32);
|
||||
|
||||
if ((elements & (1 << desc->location)) == 0)
|
||||
continue; /* Binding unused */
|
||||
|
||||
uint32_t slot = __builtin_popcount(elements & ((1 << desc->location) - 1));
|
||||
|
||||
struct GENX(VERTEX_ELEMENT_STATE) element = {
|
||||
.VertexBufferIndex = desc->binding,
|
||||
.Valid = true,
|
||||
.SourceElementFormat = format,
|
||||
.EdgeFlagEnable = false,
|
||||
.SourceElementOffset = desc->offset,
|
||||
.Component0Control = vertex_element_comp_control(format, 0),
|
||||
.Component1Control = vertex_element_comp_control(format, 1),
|
||||
.Component2Control = vertex_element_comp_control(format, 2),
|
||||
.Component3Control = vertex_element_comp_control(format, 3),
|
||||
};
|
||||
GENX(VERTEX_ELEMENT_STATE_pack)(NULL, &p[1 + slot * 2], &element);
|
||||
|
||||
#if ANV_GEN >= 8
|
||||
/* On Broadwell and later, we have a separate VF_INSTANCING packet
|
||||
* that controls instancing. On Haswell and prior, that's part of
|
||||
* VERTEX_BUFFER_STATE which we emit later.
|
||||
*/
|
||||
anv_batch_emit(&pipeline->batch, GENX(3DSTATE_VF_INSTANCING),
|
||||
.InstancingEnable = pipeline->instancing_enable[desc->binding],
|
||||
.VertexElementIndex = slot,
|
||||
/* Vulkan so far doesn't have an instance divisor, so
|
||||
* this is always 1 (ignored if not instancing). */
|
||||
.InstanceDataStepRate = 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
const uint32_t id_slot = __builtin_popcount(elements);
|
||||
#if ANV_GEN >= 8
|
||||
anv_batch_emit(&pipeline->batch, GENX(3DSTATE_VF_SGVS),
|
||||
.VertexIDEnable = pipeline->vs_prog_data.uses_vertexid,
|
||||
.VertexIDComponentNumber = 2,
|
||||
.VertexIDElementOffset = id_slot,
|
||||
.InstanceIDEnable = pipeline->vs_prog_data.uses_instanceid,
|
||||
.InstanceIDComponentNumber = 3,
|
||||
.InstanceIDElementOffset = id_slot);
|
||||
#else
|
||||
if (pipeline->vs_prog_data.uses_vertexid ||
|
||||
pipeline->vs_prog_data.uses_instanceid) {
|
||||
struct GEN7_VERTEX_ELEMENT_STATE element = {
|
||||
.Valid = true,
|
||||
/* FIXME: Do we need to provide the base vertex as component 0 here
|
||||
* to support the correct base vertex ID? */
|
||||
.Component0Control = VFCOMP_STORE_0,
|
||||
.Component1Control = VFCOMP_STORE_0,
|
||||
.Component2Control = VFCOMP_STORE_VID,
|
||||
.Component3Control = VFCOMP_STORE_IID
|
||||
};
|
||||
GEN7_VERTEX_ELEMENT_STATE_pack(NULL, &p[1 + id_slot * 2], &element);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static const uint32_t vk_to_gen_cullmode[] = {
|
||||
[VK_CULL_MODE_NONE] = CULLMODE_NONE,
|
||||
[VK_CULL_MODE_FRONT_BIT] = CULLMODE_FRONT,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue