mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-26 10:40:11 +01:00
svga: update constant buffer code for GBS
Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com> Cc: "10.1" <mesa-stable@lists.freedesktop.org>
This commit is contained in:
parent
31dfefc47f
commit
2f1fc8db10
5 changed files with 173 additions and 67 deletions
|
|
@ -53,6 +53,7 @@ DEBUG_GET_ONCE_BOOL_OPTION(force_hw_line_stipple, "SVGA_FORCE_HW_LINE_STIPPLE",
|
|||
static void svga_destroy( struct pipe_context *pipe )
|
||||
{
|
||||
struct svga_context *svga = svga_context( pipe );
|
||||
struct svga_winsys_screen *sws = svga_screen(pipe->screen)->sws;
|
||||
unsigned shader;
|
||||
|
||||
util_blitter_destroy(svga->blitter);
|
||||
|
|
@ -70,8 +71,10 @@ static void svga_destroy( struct pipe_context *pipe )
|
|||
|
||||
util_bitmask_destroy( svga->shader_id_bm );
|
||||
|
||||
for(shader = 0; shader < PIPE_SHADER_TYPES; ++shader)
|
||||
pipe_resource_reference( &svga->curr.cb[shader], NULL );
|
||||
for (shader = 0; shader < PIPE_SHADER_TYPES; ++shader) {
|
||||
pipe_resource_reference( &svga->curr.cbufs[shader].buffer, NULL );
|
||||
sws->surface_reference(sws, &svga->state.hw_draw.hw_cb[shader], NULL);
|
||||
}
|
||||
|
||||
FREE( svga );
|
||||
}
|
||||
|
|
@ -147,6 +150,7 @@ struct pipe_context *svga_context_create( struct pipe_screen *screen,
|
|||
memset(&svga->state.hw_draw, 0xcd, sizeof(svga->state.hw_draw));
|
||||
memset(&svga->state.hw_draw.views, 0x0, sizeof(svga->state.hw_draw.views));
|
||||
svga->state.hw_draw.num_views = 0;
|
||||
memset(&svga->state.hw_draw.hw_cb, 0x0, sizeof(svga->state.hw_draw.hw_cb));
|
||||
|
||||
svga->dirty = ~0;
|
||||
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ struct svga_state
|
|||
|
||||
struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS];
|
||||
struct pipe_index_buffer ib;
|
||||
struct pipe_resource *cb[PIPE_SHADER_TYPES];
|
||||
struct pipe_constant_buffer cbufs[PIPE_SHADER_TYPES];
|
||||
|
||||
struct pipe_framebuffer_state framebuffer;
|
||||
float depthscale;
|
||||
|
|
@ -287,6 +287,11 @@ struct svga_hw_draw_state
|
|||
unsigned ts[SVGA3D_PIXEL_SAMPLERREG_MAX][SVGA3D_TS_MAX];
|
||||
float cb[PIPE_SHADER_TYPES][SVGA3D_CONSTREG_MAX][4];
|
||||
|
||||
/**
|
||||
* For guest backed shader constants only.
|
||||
*/
|
||||
struct svga_winsys_surface *hw_cb[PIPE_SHADER_TYPES];
|
||||
|
||||
struct svga_shader_variant *fs;
|
||||
struct svga_shader_variant *vs;
|
||||
struct svga_hw_view_state views[PIPE_MAX_SAMPLERS];
|
||||
|
|
|
|||
|
|
@ -61,8 +61,10 @@ static void svga_set_constant_buffer(struct pipe_context *pipe,
|
|||
assert(shader < PIPE_SHADER_TYPES);
|
||||
assert(index == 0);
|
||||
|
||||
pipe_resource_reference( &svga->curr.cb[shader],
|
||||
buf );
|
||||
pipe_resource_reference(&svga->curr.cbufs[shader].buffer, buf);
|
||||
svga->curr.cbufs[shader].buffer_size = cb ? cb->buffer_size : 0;
|
||||
svga->curr.cbufs[shader].buffer_offset = cb ? cb->buffer_offset : 0;
|
||||
svga->curr.cbufs[shader].user_buffer = NULL; /* not used */
|
||||
|
||||
if (shader == PIPE_SHADER_FRAGMENT)
|
||||
svga->dirty |= SVGA_NEW_FS_CONST_BUFFER;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
**********************************************************/
|
||||
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "pipe/p_defines.h"
|
||||
|
||||
#include "svga_screen.h"
|
||||
|
|
@ -32,6 +33,7 @@
|
|||
#include "svga_cmd.h"
|
||||
#include "svga_tgsi.h"
|
||||
#include "svga_debug.h"
|
||||
#include "svga_resource_buffer.h"
|
||||
|
||||
#include "svga_hw_reg.h"
|
||||
|
||||
|
|
@ -41,7 +43,14 @@
|
|||
*/
|
||||
#define MAX_CONST_REG_COUNT 256 /**< number of float[4] constants */
|
||||
|
||||
/**
|
||||
* Extra space for svga-specific VS/PS constants (such as texcoord
|
||||
* scale factors, vertex transformation scale/translation).
|
||||
*/
|
||||
#define MAX_EXTRA_CONSTS 32
|
||||
|
||||
/** Guest-backed surface constant buffers must be this size */
|
||||
#define GB_CONSTBUF_SIZE (SVGA3D_CONSTREG_MAX)
|
||||
|
||||
/**
|
||||
* Convert from PIPE_SHADER_* to SVGA3D_SHADERTYPE_*
|
||||
|
|
@ -61,6 +70,81 @@ svga_shader_type(unsigned shader)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Emit any extra fragment shader constants into the buffer pointed
|
||||
* to by 'dest'.
|
||||
* In particular, these would be the scaling factors needed for handling
|
||||
* unnormalized texture coordinates for texture rectangles.
|
||||
* \return number of float[4] constants put into the dest buffer
|
||||
*/
|
||||
static unsigned
|
||||
svga_get_extra_fs_constants(struct svga_context *svga, float *dest)
|
||||
{
|
||||
const struct svga_shader_variant *variant = svga->state.hw_draw.fs;
|
||||
const struct svga_fs_compile_key *key = &variant->key.fkey;
|
||||
unsigned count = 0;
|
||||
|
||||
/* SVGA_NEW_VS_VARIANT
|
||||
*/
|
||||
if (key->num_unnormalized_coords) {
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < key->num_textures; i++) {
|
||||
if (key->tex[i].unnormalized) {
|
||||
struct pipe_resource *tex = svga->curr.sampler_views[i]->texture;
|
||||
|
||||
/* debug/sanity check */
|
||||
assert(key->tex[i].width_height_idx == count);
|
||||
|
||||
*dest++ = 1.0 / (float)tex->width0;
|
||||
*dest++ = 1.0 / (float)tex->height0;
|
||||
*dest++ = 1.0;
|
||||
*dest++ = 1.0;
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert(count <= MAX_EXTRA_CONSTS);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Emit any extra vertex shader constants into the buffer pointed
|
||||
* to by 'dest'.
|
||||
* In particular, these would be the scale and bias factors computed
|
||||
* from the framebuffer size which are used to copy with differences in
|
||||
* GL vs D3D coordinate spaces. See svga_tgsi_insn.c for more info.
|
||||
* \return number of float[4] constants put into the dest buffer
|
||||
*/
|
||||
static unsigned
|
||||
svga_get_extra_vs_constants(struct svga_context *svga, float *dest)
|
||||
{
|
||||
const struct svga_shader_variant *variant = svga->state.hw_draw.vs;
|
||||
const struct svga_vs_compile_key *key = &variant->key.vkey;
|
||||
unsigned count = 0;
|
||||
|
||||
/* SVGA_NEW_VS_VARIANT
|
||||
*/
|
||||
if (key->need_prescale) {
|
||||
memcpy(dest, svga->state.hw_clear.prescale.scale, 4 * sizeof(float));
|
||||
dest += 4;
|
||||
|
||||
memcpy(dest, svga->state.hw_clear.prescale.translate, 4 * sizeof(float));
|
||||
dest += 4;
|
||||
|
||||
count = 2;
|
||||
}
|
||||
|
||||
assert(count <= MAX_EXTRA_CONSTS);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check and emit one shader constant register.
|
||||
* \param shader PIPE_SHADER_FRAGMENT or PIPE_SHADER_VERTEX
|
||||
|
|
@ -120,8 +204,8 @@ emit_const_range(struct svga_context *svga,
|
|||
|
||||
#ifdef DEBUG
|
||||
if (offset + count > SVGA3D_CONSTREG_MAX) {
|
||||
debug_printf("svga: too many constants (offset + count = %u)\n",
|
||||
offset + count);
|
||||
debug_printf("svga: too many constants (offset %u + count %u = %u (max = %u))\n",
|
||||
offset, count, offset + count, SVGA3D_CONSTREG_MAX);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -185,11 +269,21 @@ emit_const_range(struct svga_context *svga,
|
|||
|
||||
/* Send them all together.
|
||||
*/
|
||||
ret = SVGA3D_SetShaderConsts(svga->swc,
|
||||
offset + i, j - i,
|
||||
svga_shader_type(shader),
|
||||
SVGA3D_CONST_TYPE_FLOAT,
|
||||
values + i);
|
||||
if (svga_have_gb_objects(svga)) {
|
||||
ret = SVGA3D_SetGBShaderConstsInline(svga->swc,
|
||||
offset + i, /* start */
|
||||
j - i, /* count */
|
||||
svga_shader_type(shader),
|
||||
SVGA3D_CONST_TYPE_FLOAT,
|
||||
values + i);
|
||||
}
|
||||
else {
|
||||
ret = SVGA3D_SetShaderConsts(svga->swc,
|
||||
offset + i, j - i,
|
||||
svga_shader_type(shader),
|
||||
SVGA3D_CONST_TYPE_FLOAT,
|
||||
values + i);
|
||||
}
|
||||
if (ret != PIPE_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -227,13 +321,11 @@ emit_consts(struct svga_context *svga, unsigned shader)
|
|||
|
||||
assert(shader < PIPE_SHADER_TYPES);
|
||||
|
||||
if (svga->curr.cb[shader] == NULL)
|
||||
if (svga->curr.cbufs[shader].buffer == NULL)
|
||||
goto done;
|
||||
|
||||
count = svga->curr.cb[shader]->width0 / (4 * sizeof(float));
|
||||
|
||||
data = (const float (*)[4])pipe_buffer_map(&svga->pipe,
|
||||
svga->curr.cb[shader],
|
||||
svga->curr.cbufs[shader].buffer,
|
||||
PIPE_TRANSFER_READ,
|
||||
&transfer);
|
||||
if (data == NULL) {
|
||||
|
|
@ -241,6 +333,14 @@ emit_consts(struct svga_context *svga, unsigned shader)
|
|||
goto done;
|
||||
}
|
||||
|
||||
/* sanity check */
|
||||
assert(svga->curr.cbufs[shader].buffer->width0 >=
|
||||
svga->curr.cbufs[shader].buffer_size);
|
||||
|
||||
/* Use/apply the constant buffer size and offsets here */
|
||||
count = svga->curr.cbufs[shader].buffer_size / (4 * sizeof(float));
|
||||
data += svga->curr.cbufs[shader].buffer_offset / (4 * sizeof(float));
|
||||
|
||||
if (ss->hw_version >= SVGA3D_HWVERSION_WS8_B1) {
|
||||
ret = emit_const_range( svga, shader, offset, count, data );
|
||||
if (ret != PIPE_OK) {
|
||||
|
|
@ -266,47 +366,42 @@ done:
|
|||
static enum pipe_error
|
||||
emit_fs_consts(struct svga_context *svga, unsigned dirty)
|
||||
{
|
||||
struct svga_screen *ss = svga_screen(svga->pipe.screen);
|
||||
const struct svga_shader_variant *variant = svga->state.hw_draw.fs;
|
||||
enum pipe_error ret = PIPE_OK;
|
||||
|
||||
/* SVGA_NEW_FS_VARIANT
|
||||
*/
|
||||
if (variant == NULL)
|
||||
return PIPE_OK;
|
||||
|
||||
/* SVGA_NEW_FS_CONST_BUFFER
|
||||
*/
|
||||
ret = emit_consts( svga, PIPE_SHADER_FRAGMENT );
|
||||
if (ret != PIPE_OK)
|
||||
return ret;
|
||||
|
||||
/* The internally generated fragment shader for xor blending
|
||||
* doesn't have a 'variant' struct. It should be fixed to avoid
|
||||
* this special case, but work around it with a NULL check:
|
||||
*/
|
||||
if (variant) {
|
||||
const struct svga_fs_compile_key *key = &variant->key.fkey;
|
||||
if (key->num_unnormalized_coords) {
|
||||
const unsigned offset =
|
||||
variant->shader->info.file_max[TGSI_FILE_CONSTANT] + 1;
|
||||
unsigned i;
|
||||
/* emit extra shader constants */
|
||||
{
|
||||
unsigned offset = variant->shader->info.file_max[TGSI_FILE_CONSTANT] + 1;
|
||||
float extras[MAX_EXTRA_CONSTS][4];
|
||||
unsigned count, i;
|
||||
|
||||
for (i = 0; i < key->num_textures; i++) {
|
||||
if (key->tex[i].unnormalized) {
|
||||
struct pipe_resource *tex = svga->curr.sampler_views[i]->texture;
|
||||
float data[4];
|
||||
count = svga_get_extra_fs_constants(svga, (float *) extras);
|
||||
|
||||
data[0] = 1.0f / (float) tex->width0;
|
||||
data[1] = 1.0f / (float) tex->height0;
|
||||
data[2] = 1.0f;
|
||||
data[3] = 1.0f;
|
||||
|
||||
ret = emit_const(svga,
|
||||
PIPE_SHADER_FRAGMENT,
|
||||
key->tex[i].width_height_idx + offset,
|
||||
data);
|
||||
if (ret != PIPE_OK) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (ss->hw_version >= SVGA3D_HWVERSION_WS8_B1) {
|
||||
ret = emit_const_range(svga, PIPE_SHADER_FRAGMENT, offset, count,
|
||||
(const float (*) [4])extras);
|
||||
} else {
|
||||
for (i = 0; i < count; i++) {
|
||||
ret = emit_const(svga, PIPE_SHADER_FRAGMENT, offset + i, extras[i]);
|
||||
if (ret != PIPE_OK)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return PIPE_OK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -324,43 +419,43 @@ struct svga_tracked_state svga_hw_fs_constants =
|
|||
static enum pipe_error
|
||||
emit_vs_consts(struct svga_context *svga, unsigned dirty)
|
||||
{
|
||||
struct svga_screen *ss = svga_screen(svga->pipe.screen);
|
||||
const struct svga_shader_variant *variant = svga->state.hw_draw.vs;
|
||||
const struct svga_vs_compile_key *key;
|
||||
enum pipe_error ret = PIPE_OK;
|
||||
unsigned offset;
|
||||
|
||||
/* SVGA_NEW_VS_VARIANT
|
||||
*/
|
||||
if (variant == NULL)
|
||||
return PIPE_OK;
|
||||
|
||||
key = &variant->key.vkey;
|
||||
|
||||
/* SVGA_NEW_VS_CONST_BUFFER
|
||||
*/
|
||||
ret = emit_consts( svga, PIPE_SHADER_VERTEX );
|
||||
if (ret != PIPE_OK)
|
||||
return ret;
|
||||
|
||||
/* offset = number of constants in the VS const buffer */
|
||||
offset = variant->shader->info.file_max[TGSI_FILE_CONSTANT] + 1;
|
||||
/* emit extra shader constants */
|
||||
{
|
||||
unsigned offset = variant->shader->info.file_max[TGSI_FILE_CONSTANT] + 1;
|
||||
float extras[MAX_EXTRA_CONSTS][4];
|
||||
unsigned count, i;
|
||||
|
||||
/* SVGA_NEW_VS_PRESCALE
|
||||
* Put the viewport pre-scale/translate values into the const buffer.
|
||||
*/
|
||||
if (key->need_prescale) {
|
||||
ret = emit_const( svga, PIPE_SHADER_VERTEX, offset++,
|
||||
svga->state.hw_clear.prescale.scale );
|
||||
if (ret != PIPE_OK)
|
||||
return ret;
|
||||
count = svga_get_extra_vs_constants(svga, (float *) extras);
|
||||
assert(count <= Elements(extras));
|
||||
|
||||
ret = emit_const( svga, PIPE_SHADER_VERTEX, offset++,
|
||||
svga->state.hw_clear.prescale.translate );
|
||||
if (ret != PIPE_OK)
|
||||
return ret;
|
||||
if (ss->hw_version >= SVGA3D_HWVERSION_WS8_B1) {
|
||||
ret = emit_const_range(svga, PIPE_SHADER_VERTEX, offset, count,
|
||||
(const float (*) [4]) extras);
|
||||
} else {
|
||||
for (i = 0; i < count; i++) {
|
||||
ret = emit_const(svga, PIPE_SHADER_VERTEX, offset + i, extras[i]);
|
||||
if (ret != PIPE_OK)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return PIPE_OK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -88,16 +88,16 @@ svga_swtnl_draw_vbo(struct svga_context *svga,
|
|||
svga->curr.ib.index_size, ~0);
|
||||
}
|
||||
|
||||
if (svga->curr.cb[PIPE_SHADER_VERTEX]) {
|
||||
if (svga->curr.cbufs[PIPE_SHADER_VERTEX].buffer) {
|
||||
map = pipe_buffer_map(&svga->pipe,
|
||||
svga->curr.cb[PIPE_SHADER_VERTEX],
|
||||
svga->curr.cbufs[PIPE_SHADER_VERTEX].buffer,
|
||||
PIPE_TRANSFER_READ,
|
||||
&cb_transfer);
|
||||
assert(map);
|
||||
draw_set_mapped_constant_buffer(
|
||||
draw, PIPE_SHADER_VERTEX, 0,
|
||||
map,
|
||||
svga->curr.cb[PIPE_SHADER_VERTEX]->width0);
|
||||
svga->curr.cbufs[PIPE_SHADER_VERTEX].buffer->width0);
|
||||
}
|
||||
|
||||
draw_vbo(draw, info);
|
||||
|
|
@ -122,7 +122,7 @@ svga_swtnl_draw_vbo(struct svga_context *svga,
|
|||
draw_set_indexes(draw, NULL, 0, 0);
|
||||
}
|
||||
|
||||
if (svga->curr.cb[PIPE_SHADER_VERTEX]) {
|
||||
if (svga->curr.cbufs[PIPE_SHADER_VERTEX].buffer) {
|
||||
pipe_buffer_unmap(&svga->pipe, cb_transfer);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue