aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/svga/svga_swtnl_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/svga/svga_swtnl_state.c')
-rw-r--r--src/gallium/drivers/svga/svga_swtnl_state.c169
1 files changed, 143 insertions, 26 deletions
diff --git a/src/gallium/drivers/svga/svga_swtnl_state.c b/src/gallium/drivers/svga/svga_swtnl_state.c
index e62698e11f4..79dc0bf580c 100644
--- a/src/gallium/drivers/svga/svga_swtnl_state.c
+++ b/src/gallium/drivers/svga/svga_swtnl_state.c
@@ -25,10 +25,13 @@
#include "draw/draw_context.h"
#include "draw/draw_vbuf.h"
+#include "util/u_bitmask.h"
#include "util/u_inlines.h"
#include "pipe/p_state.h"
+#include "svga_cmd.h"
#include "svga_context.h"
+#include "svga_shader.h"
#include "svga_swtnl.h"
#include "svga_state.h"
#include "svga_tgsi.h"
@@ -51,30 +54,37 @@ static void set_draw_viewport( struct svga_context *svga )
float adjx = 0.0f;
float adjy = 0.0f;
- switch (svga->curr.reduced_prim) {
- case PIPE_PRIM_POINTS:
- adjx = SVGA_POINT_ADJ_X;
- adjy = SVGA_POINT_ADJ_Y;
- break;
- case PIPE_PRIM_LINES:
- /* XXX: This is to compensate for the fact that wide lines are
- * going to be drawn with triangles, but we're not catching all
- * cases where that will happen.
- */
- if (svga->curr.rast->need_pipeline & SVGA_PIPELINE_FLAG_LINES)
- {
- adjx = SVGA_LINE_ADJ_X + 0.175f;
- adjy = SVGA_LINE_ADJ_Y - 0.175f;
+ if (svga_have_vgpu10(svga)) {
+ if (svga->curr.reduced_prim == PIPE_PRIM_TRIANGLES) {
+ adjy = 0.25;
}
- else {
- adjx = SVGA_LINE_ADJ_X;
- adjy = SVGA_LINE_ADJ_Y;
+ }
+ else {
+ switch (svga->curr.reduced_prim) {
+ case PIPE_PRIM_POINTS:
+ adjx = SVGA_POINT_ADJ_X;
+ adjy = SVGA_POINT_ADJ_Y;
+ break;
+ case PIPE_PRIM_LINES:
+ /* XXX: This is to compensate for the fact that wide lines are
+ * going to be drawn with triangles, but we're not catching all
+ * cases where that will happen.
+ */
+ if (svga->curr.rast->need_pipeline & SVGA_PIPELINE_FLAG_LINES)
+ {
+ adjx = SVGA_LINE_ADJ_X + 0.175f;
+ adjy = SVGA_LINE_ADJ_Y - 0.175f;
+ }
+ else {
+ adjx = SVGA_LINE_ADJ_X;
+ adjy = SVGA_LINE_ADJ_Y;
+ }
+ break;
+ case PIPE_PRIM_TRIANGLES:
+ adjx += SVGA_TRIANGLE_ADJ_X;
+ adjy += SVGA_TRIANGLE_ADJ_Y;
+ break;
}
- break;
- case PIPE_PRIM_TRIANGLES:
- adjx += SVGA_TRIANGLE_ADJ_X;
- adjy += SVGA_TRIANGLE_ADJ_Y;
- break;
}
vp.translate[0] += adjx;
@@ -150,6 +160,59 @@ struct svga_tracked_state svga_update_swtnl_draw =
};
+static SVGA3dSurfaceFormat
+translate_vertex_format(SVGA3dDeclType format)
+{
+ switch (format) {
+ case SVGA3D_DECLTYPE_FLOAT1:
+ return SVGA3D_R32_FLOAT;
+ case SVGA3D_DECLTYPE_FLOAT2:
+ return SVGA3D_R32G32_FLOAT;
+ case SVGA3D_DECLTYPE_FLOAT3:
+ return SVGA3D_R32G32B32_FLOAT;
+ case SVGA3D_DECLTYPE_FLOAT4:
+ return SVGA3D_R32G32B32A32_FLOAT;
+ default:
+ assert(!"Unexpected format in translate_vertex_format()");
+ return SVGA3D_R32G32B32A32_FLOAT;
+ }
+}
+
+
+static SVGA3dElementLayoutId
+svga_vdecl_to_input_element(struct svga_context *svga,
+ const SVGA3dVertexDecl *vdecl, unsigned num_decls)
+{
+ SVGA3dElementLayoutId id;
+ SVGA3dInputElementDesc elements[PIPE_MAX_ATTRIBS];
+ enum pipe_error ret;
+ unsigned i;
+
+ assert(num_decls <= PIPE_MAX_ATTRIBS);
+ assert(svga_have_vgpu10(svga));
+
+ for (i = 0; i < num_decls; i++) {
+ elements[i].inputSlot = 0; /* vertex buffer index */
+ elements[i].alignedByteOffset = vdecl[i].array.offset;
+ elements[i].format = translate_vertex_format(vdecl[i].identity.type);
+ elements[i].inputSlotClass = SVGA3D_INPUT_PER_VERTEX_DATA;
+ elements[i].instanceDataStepRate = 0;
+ elements[i].inputRegister = i;
+ }
+
+ id = util_bitmask_add(svga->input_element_object_id_bm);
+
+ ret = SVGA3D_vgpu10_DefineElementLayout(svga->swc, num_decls, id, elements);
+ if (ret != PIPE_OK) {
+ svga_context_flush(svga, NULL);
+ ret = SVGA3D_vgpu10_DefineElementLayout(svga->swc, num_decls, id, elements);
+ assert(ret == PIPE_OK);
+ }
+
+ return id;
+}
+
+
enum pipe_error
svga_swtnl_update_vdecl( struct svga_context *svga )
{
@@ -164,16 +227,19 @@ svga_swtnl_update_vdecl( struct svga_context *svga )
int nr_decls = 0;
int src;
unsigned i;
+ int any_change;
memset(vinfo, 0, sizeof(*vinfo));
memset(vdecl, 0, sizeof(vdecl));
draw_prepare_shader_outputs(draw);
+
/* always add position */
src = draw_find_shader_output(draw, TGSI_SEMANTIC_POSITION, 0);
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_LINEAR, src);
vinfo->attrib[0].emit = EMIT_4F;
vdecl[0].array.offset = offset;
+ vdecl[0].identity.method = SVGA3D_DECLMETHOD_DEFAULT;
vdecl[0].identity.type = SVGA3D_DECLTYPE_FLOAT4;
vdecl[0].identity.usage = SVGA3D_DECLUSAGE_POSITIONT;
vdecl[0].identity.usageIndex = 0;
@@ -225,16 +291,67 @@ svga_swtnl_update_vdecl( struct svga_context *svga )
draw_compute_vertex_size(vinfo);
svga_render->vdecl_count = nr_decls;
- for (i = 0; i < svga_render->vdecl_count; i++)
+ for (i = 0; i < svga_render->vdecl_count; i++) {
vdecl[i].array.stride = offset;
+ }
- if (memcmp(svga_render->vdecl, vdecl, sizeof(vdecl)) == 0)
- return PIPE_OK;
+ any_change = memcmp(svga_render->vdecl, vdecl, sizeof(vdecl));
+
+ if (svga_have_vgpu10(svga)) {
+ enum pipe_error ret;
+
+ if (!any_change && svga_render->layout_id != SVGA3D_INVALID_ID) {
+ return PIPE_OK;
+ }
+
+ if (svga_render->layout_id != SVGA3D_INVALID_ID) {
+ /* destroy old */
+ ret = SVGA3D_vgpu10_DestroyElementLayout(svga->swc,
+ svga_render->layout_id);
+ if (ret != PIPE_OK) {
+ svga_context_flush(svga, NULL);
+ ret = SVGA3D_vgpu10_DestroyElementLayout(svga->swc,
+ svga_render->layout_id);
+ assert(ret == PIPE_OK);
+ }
+
+ /**
+ * reset current layout id state after the element layout is
+ * destroyed, so that if a new layout has the same layout id, we
+ * will know to re-issue the SetInputLayout command.
+ */
+ if (svga->state.hw_draw.layout_id == svga_render->layout_id)
+ svga->state.hw_draw.layout_id = SVGA3D_INVALID_ID;
+
+ util_bitmask_clear(svga->input_element_object_id_bm,
+ svga_render->layout_id);
+ }
+
+ svga_render->layout_id =
+ svga_vdecl_to_input_element(svga, vdecl, nr_decls);
+
+ /* bind new */
+ if (svga->state.hw_draw.layout_id != svga_render->layout_id) {
+ ret = SVGA3D_vgpu10_SetInputLayout(svga->swc, svga_render->layout_id);
+ if (ret != PIPE_OK) {
+ svga_context_flush(svga, NULL);
+ ret = SVGA3D_vgpu10_SetInputLayout(svga->swc,
+ svga_render->layout_id);
+ assert(ret == PIPE_OK);
+ }
+
+ svga->state.hw_draw.layout_id = svga_render->layout_id;
+ }
+ }
+ else {
+ if (!any_change)
+ return PIPE_OK;
+ }
memcpy(svga_render->vdecl, vdecl, sizeof(vdecl));
svga->swtnl.new_vdecl = TRUE;
- return PIPE_OK;
+ return 0;
}