mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-01 01:00:10 +01:00
softpipe: add SSBO/shader atomics support.
This adds support for the features requires for ARB_shader_storage_buffer_object and ARB_shader_atomic_counters, ARB_shader_atomic_counter_ops. [airlied: some cleanups applied] Reviewed-by: Brian Paul <brianp@vmware.com> Reviewed-by: Roland Scheidegger <sroland@vmware.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
c2aeeca455
commit
afa8707ba9
13 changed files with 473 additions and 11 deletions
|
|
@ -150,7 +150,7 @@ GL 4.2, GLSL 4.20:
|
|||
|
||||
GL_ARB_texture_compression_bptc DONE (i965, nvc0, r600, radeonsi)
|
||||
GL_ARB_compressed_texture_pixel_storage DONE (all drivers)
|
||||
GL_ARB_shader_atomic_counters DONE (i965, nvc0)
|
||||
GL_ARB_shader_atomic_counters DONE (i965, nvc0, softpipe)
|
||||
GL_ARB_texture_storage DONE (all drivers)
|
||||
GL_ARB_transform_feedback_instanced DONE (i965, nv50, nvc0, r600, radeonsi, llvmpipe, softpipe)
|
||||
GL_ARB_base_instance DONE (i965, nv50, nvc0, r600, radeonsi, llvmpipe, softpipe)
|
||||
|
|
@ -179,7 +179,7 @@ GL 4.3, GLSL 4.30:
|
|||
GL_ARB_program_interface_query DONE (all drivers)
|
||||
GL_ARB_robust_buffer_access_behavior not started
|
||||
GL_ARB_shader_image_size DONE (i965, radeonsi, softpipe)
|
||||
GL_ARB_shader_storage_buffer_object DONE (i965, nvc0)
|
||||
GL_ARB_shader_storage_buffer_object DONE (i965, nvc0, softpipe)
|
||||
GL_ARB_stencil_texturing DONE (i965/gen8+, nv50, nvc0, r600, radeonsi, llvmpipe, softpipe)
|
||||
GL_ARB_texture_buffer_range DONE (nv50, nvc0, i965, r600, radeonsi, llvmpipe)
|
||||
GL_ARB_texture_query_levels DONE (all drivers that support GLSL 1.30)
|
||||
|
|
@ -230,10 +230,10 @@ GLES3.1, GLSL ES 3.1
|
|||
GL_ARB_explicit_uniform_location DONE (all drivers that support GLSL)
|
||||
GL_ARB_framebuffer_no_attachments DONE (i965, nvc0, r600, radeonsi)
|
||||
GL_ARB_program_interface_query DONE (all drivers)
|
||||
GL_ARB_shader_atomic_counters DONE (i965, nvc0)
|
||||
GL_ARB_shader_atomic_counters DONE (i965, nvc0, softpipe)
|
||||
GL_ARB_shader_image_load_store DONE (i965, softpipe, radeonsi)
|
||||
GL_ARB_shader_image_size DONE (i965, softpipe, radeonsi)
|
||||
GL_ARB_shader_storage_buffer_object DONE (i965, nvc0)
|
||||
GL_ARB_shader_storage_buffer_object DONE (i965, nvc0, softpipe)
|
||||
GL_ARB_shading_language_packing DONE (all drivers)
|
||||
GL_ARB_separate_shader_objects DONE (all drivers)
|
||||
GL_ARB_stencil_texturing DONE (i965/gen8+, nv50, nvc0, r600, radeonsi, llvmpipe, softpipe)
|
||||
|
|
|
|||
|
|
@ -46,9 +46,11 @@ Note: some of the new features are only available with certain drivers.
|
|||
<ul>
|
||||
<li>GL_ARB_framebuffer_no_attachments on nvc0, r600, radeonsi</li>
|
||||
<li>GL_ARB_internalformat_query2 on all drivers</li>
|
||||
<li>GL_ARB_shader_atomic_counter_ops on nvc0</li>
|
||||
<li>GL_ARB_shader_atomic_counters on softpipe</li>
|
||||
<li>GL_ARB_shader_atomic_counter_ops on nvc0, softpipe</li>
|
||||
<li>GL_ARB_shader_image_load_store on radeonsi, softpipe</li>
|
||||
<li>GL_ARB_shader_image_size on radeonsi, softpipe</li>
|
||||
<li>GL_ARB_shader_storage_buffer_objects on softpipe</li>
|
||||
<li>GL_ATI_fragment_shader on all Gallium drivers</li>
|
||||
<li>GL_EXT_base_instance on all drivers that support GL_ARB_base_instance</li>
|
||||
<li>GL_OES_draw_buffers_indexed and GL_EXT_draw_buffers_indexed on all drivers that support GL_ARB_draw_buffers_blend</li>
|
||||
|
|
|
|||
|
|
@ -528,8 +528,9 @@ tgsi_exec_get_shader_param(enum pipe_shader_cap param)
|
|||
return 1;
|
||||
case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
|
||||
case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
|
||||
case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
|
||||
return 0;
|
||||
case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
|
||||
return PIPE_MAX_SHADER_BUFFERS;
|
||||
case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
|
||||
return PIPE_MAX_SHADER_IMAGES;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
C_SOURCES := \
|
||||
sp_buffer.c \
|
||||
sp_clear.c \
|
||||
sp_clear.h \
|
||||
sp_context.c \
|
||||
|
|
|
|||
371
src/gallium/drivers/softpipe/sp_buffer.c
Normal file
371
src/gallium/drivers/softpipe/sp_buffer.c
Normal file
|
|
@ -0,0 +1,371 @@
|
|||
/*
|
||||
* Copyright 2016 Red Hat.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
* license, and/or sell copies of the Software, and to permit persons to whom
|
||||
* the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "sp_context.h"
|
||||
#include "sp_buffer.h"
|
||||
#include "sp_texture.h"
|
||||
|
||||
#include "util/u_format.h"
|
||||
|
||||
static bool
|
||||
get_dimensions(const struct pipe_shader_buffer *bview,
|
||||
const struct softpipe_resource *spr,
|
||||
unsigned *width)
|
||||
{
|
||||
*width = bview->buffer_size;
|
||||
/*
|
||||
* Bounds check the buffer size from the view
|
||||
* and the buffer size from the underlying buffer.
|
||||
*/
|
||||
if (*width > spr->base.width0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Implement the image LOAD operation.
|
||||
*/
|
||||
static void
|
||||
sp_tgsi_load(const struct tgsi_buffer *buffer,
|
||||
const struct tgsi_buffer_params *params,
|
||||
const int s[TGSI_QUAD_SIZE],
|
||||
float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
|
||||
{
|
||||
struct sp_tgsi_buffer *sp_buf = (struct sp_tgsi_buffer *)buffer;
|
||||
struct pipe_shader_buffer *bview;
|
||||
struct softpipe_resource *spr;
|
||||
unsigned width;
|
||||
int c, j;
|
||||
unsigned char *data_ptr;
|
||||
const struct util_format_description *format_desc = util_format_description(PIPE_FORMAT_R32_UINT);
|
||||
|
||||
if (params->unit > PIPE_MAX_SHADER_BUFFERS)
|
||||
goto fail_write_all_zero;
|
||||
|
||||
bview = &sp_buf->sp_bview[params->unit];
|
||||
spr = softpipe_resource(bview->buffer);
|
||||
if (!spr)
|
||||
goto fail_write_all_zero;
|
||||
|
||||
if (!get_dimensions(bview, spr, &width))
|
||||
return;
|
||||
|
||||
for (j = 0; j < TGSI_QUAD_SIZE; j++) {
|
||||
int s_coord;
|
||||
bool fill_zero = false;
|
||||
uint32_t sdata[4];
|
||||
|
||||
if (!(params->execmask & (1 << j)))
|
||||
fill_zero = true;
|
||||
|
||||
s_coord = s[j];
|
||||
if (s_coord >= width)
|
||||
fill_zero = true;
|
||||
|
||||
if (fill_zero) {
|
||||
for (c = 0; c < 4; c++)
|
||||
rgba[c][j] = 0;
|
||||
continue;
|
||||
}
|
||||
data_ptr = (unsigned char *)spr->data + bview->buffer_offset + s_coord;
|
||||
for (c = 0; c < 4; c++) {
|
||||
format_desc->fetch_rgba_uint(sdata, data_ptr, 0, 0);
|
||||
((uint32_t *)rgba[c])[j] = sdata[0];
|
||||
data_ptr += 4;
|
||||
}
|
||||
}
|
||||
return;
|
||||
fail_write_all_zero:
|
||||
memset(rgba, 0, TGSI_NUM_CHANNELS * TGSI_QUAD_SIZE * 4);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Implement the buffer STORE operation.
|
||||
*/
|
||||
static void
|
||||
sp_tgsi_store(const struct tgsi_buffer *buffer,
|
||||
const struct tgsi_buffer_params *params,
|
||||
const int s[TGSI_QUAD_SIZE],
|
||||
float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
|
||||
{
|
||||
struct sp_tgsi_buffer *sp_buf = (struct sp_tgsi_buffer *)buffer;
|
||||
struct pipe_shader_buffer *bview;
|
||||
struct softpipe_resource *spr;
|
||||
unsigned width;
|
||||
unsigned char *data_ptr;
|
||||
int j, c;
|
||||
const struct util_format_description *format_desc = util_format_description(PIPE_FORMAT_R32_UINT);
|
||||
|
||||
if (params->unit > PIPE_MAX_SHADER_BUFFERS)
|
||||
return;
|
||||
|
||||
bview = &sp_buf->sp_bview[params->unit];
|
||||
spr = softpipe_resource(bview->buffer);
|
||||
if (!spr)
|
||||
return;
|
||||
|
||||
if (!get_dimensions(bview, spr, &width))
|
||||
return;
|
||||
|
||||
for (j = 0; j < TGSI_QUAD_SIZE; j++) {
|
||||
int s_coord;
|
||||
|
||||
if (!(params->execmask & (1 << j)))
|
||||
continue;
|
||||
|
||||
s_coord = s[j];
|
||||
if (s_coord >= width)
|
||||
continue;
|
||||
|
||||
data_ptr = (unsigned char *)spr->data + bview->buffer_offset + s_coord;
|
||||
|
||||
for (c = 0; c < 4; c++) {
|
||||
if (params->writemask & (1 << c)) {
|
||||
unsigned temp[4];
|
||||
unsigned char *dptr = data_ptr + (c * 4);
|
||||
temp[0] = ((uint32_t *)rgba[c])[j];
|
||||
format_desc->pack_rgba_uint(dptr, 0, temp, 0, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Implement atomic operations on unsigned integers.
|
||||
*/
|
||||
static void
|
||||
handle_op_uint(const struct pipe_shader_buffer *bview,
|
||||
bool just_read,
|
||||
unsigned char *data_ptr,
|
||||
uint qi,
|
||||
unsigned opcode,
|
||||
unsigned writemask,
|
||||
float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE],
|
||||
float rgba2[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
|
||||
{
|
||||
uint c;
|
||||
const struct util_format_description *format_desc = util_format_description(PIPE_FORMAT_R32_UINT);
|
||||
unsigned sdata[4];
|
||||
|
||||
for (c = 0; c < 4; c++) {
|
||||
unsigned temp[4];
|
||||
unsigned char *dptr = data_ptr + (c * 4);
|
||||
format_desc->fetch_rgba_uint(temp, dptr, 0, 0);
|
||||
sdata[c] = temp[0];
|
||||
}
|
||||
|
||||
if (just_read) {
|
||||
for (c = 0; c < 4; c++) {
|
||||
((uint32_t *)rgba[c])[qi] = sdata[c];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
switch (opcode) {
|
||||
case TGSI_OPCODE_ATOMUADD:
|
||||
for (c = 0; c < 4; c++) {
|
||||
unsigned temp = sdata[c];
|
||||
sdata[c] += ((uint32_t *)rgba[c])[qi];
|
||||
((uint32_t *)rgba[c])[qi] = temp;
|
||||
}
|
||||
break;
|
||||
case TGSI_OPCODE_ATOMXCHG:
|
||||
for (c = 0; c < 4; c++) {
|
||||
unsigned temp = sdata[c];
|
||||
sdata[c] = ((uint32_t *)rgba[c])[qi];
|
||||
((uint32_t *)rgba[c])[qi] = temp;
|
||||
}
|
||||
break;
|
||||
case TGSI_OPCODE_ATOMCAS:
|
||||
for (c = 0; c < 4; c++) {
|
||||
unsigned dst_x = sdata[c];
|
||||
unsigned cmp_x = ((uint32_t *)rgba[c])[qi];
|
||||
unsigned src_x = ((uint32_t *)rgba2[c])[qi];
|
||||
unsigned temp = sdata[c];
|
||||
sdata[c] = (dst_x == cmp_x) ? src_x : dst_x;
|
||||
((uint32_t *)rgba[c])[qi] = temp;
|
||||
}
|
||||
break;
|
||||
case TGSI_OPCODE_ATOMAND:
|
||||
for (c = 0; c < 4; c++) {
|
||||
unsigned temp = sdata[c];
|
||||
sdata[c] &= ((uint32_t *)rgba[c])[qi];
|
||||
((uint32_t *)rgba[c])[qi] = temp;
|
||||
}
|
||||
break;
|
||||
case TGSI_OPCODE_ATOMOR:
|
||||
for (c = 0; c < 4; c++) {
|
||||
unsigned temp = sdata[c];
|
||||
sdata[c] |= ((uint32_t *)rgba[c])[qi];
|
||||
((uint32_t *)rgba[c])[qi] = temp;
|
||||
}
|
||||
break;
|
||||
case TGSI_OPCODE_ATOMXOR:
|
||||
for (c = 0; c < 4; c++) {
|
||||
unsigned temp = sdata[c];
|
||||
sdata[c] ^= ((uint32_t *)rgba[c])[qi];
|
||||
((uint32_t *)rgba[c])[qi] = temp;
|
||||
}
|
||||
break;
|
||||
case TGSI_OPCODE_ATOMUMIN:
|
||||
for (c = 0; c < 4; c++) {
|
||||
unsigned dst_x = sdata[c];
|
||||
unsigned src_x = ((uint32_t *)rgba[c])[qi];
|
||||
sdata[c] = MIN2(dst_x, src_x);
|
||||
((uint32_t *)rgba[c])[qi] = dst_x;
|
||||
}
|
||||
break;
|
||||
case TGSI_OPCODE_ATOMUMAX:
|
||||
for (c = 0; c < 4; c++) {
|
||||
unsigned dst_x = sdata[c];
|
||||
unsigned src_x = ((uint32_t *)rgba[c])[qi];
|
||||
sdata[c] = MAX2(dst_x, src_x);
|
||||
((uint32_t *)rgba[c])[qi] = dst_x;
|
||||
}
|
||||
break;
|
||||
case TGSI_OPCODE_ATOMIMIN:
|
||||
for (c = 0; c < 4; c++) {
|
||||
int dst_x = sdata[c];
|
||||
int src_x = ((uint32_t *)rgba[c])[qi];
|
||||
sdata[c] = MIN2(dst_x, src_x);
|
||||
((uint32_t *)rgba[c])[qi] = dst_x;
|
||||
}
|
||||
break;
|
||||
case TGSI_OPCODE_ATOMIMAX:
|
||||
for (c = 0; c < 4; c++) {
|
||||
int dst_x = sdata[c];
|
||||
int src_x = ((uint32_t *)rgba[c])[qi];
|
||||
sdata[c] = MAX2(dst_x, src_x);
|
||||
((uint32_t *)rgba[c])[qi] = dst_x;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(!"Unexpected TGSI opcode in sp_tgsi_op");
|
||||
break;
|
||||
}
|
||||
|
||||
for (c = 0; c < 4; c++) {
|
||||
if (writemask & (1 << c)) {
|
||||
unsigned temp[4];
|
||||
unsigned char *dptr = data_ptr + (c * 4);
|
||||
temp[0] = sdata[c];
|
||||
format_desc->pack_rgba_uint(dptr, 0, temp, 0, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Implement atomic buffer operations.
|
||||
*/
|
||||
static void
|
||||
sp_tgsi_op(const struct tgsi_buffer *buffer,
|
||||
const struct tgsi_buffer_params *params,
|
||||
unsigned opcode,
|
||||
const int s[TGSI_QUAD_SIZE],
|
||||
float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE],
|
||||
float rgba2[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
|
||||
{
|
||||
struct sp_tgsi_buffer *sp_buf = (struct sp_tgsi_buffer *)buffer;
|
||||
struct pipe_shader_buffer *bview;
|
||||
struct softpipe_resource *spr;
|
||||
unsigned width;
|
||||
int j, c;
|
||||
unsigned char *data_ptr;
|
||||
|
||||
if (params->unit > PIPE_MAX_SHADER_BUFFERS)
|
||||
return;
|
||||
|
||||
bview = &sp_buf->sp_bview[params->unit];
|
||||
spr = softpipe_resource(bview->buffer);
|
||||
if (!spr)
|
||||
goto fail_write_all_zero;
|
||||
|
||||
if (!get_dimensions(bview, spr, &width))
|
||||
goto fail_write_all_zero;
|
||||
|
||||
for (j = 0; j < TGSI_QUAD_SIZE; j++) {
|
||||
int s_coord;
|
||||
bool just_read = false;
|
||||
|
||||
s_coord = s[j];
|
||||
if (s_coord >= width) {
|
||||
for (c = 0; c < 4; c++) {
|
||||
rgba[c][j] = 0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* just readback the value for atomic if execmask isn't set */
|
||||
if (!(params->execmask & (1 << j))) {
|
||||
just_read = true;
|
||||
}
|
||||
|
||||
data_ptr = (unsigned char *)spr->data + bview->buffer_offset + s_coord;
|
||||
/* we should see atomic operations on r32 formats */
|
||||
|
||||
handle_op_uint(bview, just_read, data_ptr, j,
|
||||
opcode, params->writemask, rgba, rgba2);
|
||||
}
|
||||
return;
|
||||
fail_write_all_zero:
|
||||
memset(rgba, 0, TGSI_NUM_CHANNELS * TGSI_QUAD_SIZE * 4);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* return size of the attached buffer for RESQ opcode.
|
||||
*/
|
||||
static void
|
||||
sp_tgsi_get_dims(const struct tgsi_buffer *buffer,
|
||||
const struct tgsi_buffer_params *params,
|
||||
int *dim)
|
||||
{
|
||||
struct sp_tgsi_buffer *sp_buf = (struct sp_tgsi_buffer *)buffer;
|
||||
struct pipe_shader_buffer *bview;
|
||||
struct softpipe_resource *spr;
|
||||
|
||||
if (params->unit > PIPE_MAX_SHADER_BUFFERS)
|
||||
return;
|
||||
|
||||
bview = &sp_buf->sp_bview[params->unit];
|
||||
spr = softpipe_resource(bview->buffer);
|
||||
if (!spr)
|
||||
return;
|
||||
|
||||
*dim = bview->buffer_size;
|
||||
}
|
||||
|
||||
struct sp_tgsi_buffer *
|
||||
sp_create_tgsi_buffer(void)
|
||||
{
|
||||
struct sp_tgsi_buffer *buf = CALLOC_STRUCT(sp_tgsi_buffer);
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
buf->base.load = sp_tgsi_load;
|
||||
buf->base.store = sp_tgsi_store;
|
||||
buf->base.op = sp_tgsi_op;
|
||||
buf->base.get_dims = sp_tgsi_get_dims;
|
||||
return buf;
|
||||
};
|
||||
37
src/gallium/drivers/softpipe/sp_buffer.h
Normal file
37
src/gallium/drivers/softpipe/sp_buffer.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2016 Red Hat.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
* license, and/or sell copies of the Software, and to permit persons to whom
|
||||
* the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SP_BUFFER_H
|
||||
#define SP_BUFFER_H
|
||||
#include "tgsi/tgsi_exec.h"
|
||||
|
||||
struct sp_tgsi_buffer
|
||||
{
|
||||
struct tgsi_buffer base;
|
||||
struct pipe_shader_buffer sp_bview[PIPE_MAX_SHADER_BUFFERS];
|
||||
};
|
||||
|
||||
struct sp_tgsi_buffer *
|
||||
sp_create_tgsi_buffer(void);
|
||||
|
||||
#endif
|
||||
|
|
@ -38,6 +38,7 @@
|
|||
#include "util/u_pstipple.h"
|
||||
#include "util/u_inlines.h"
|
||||
#include "tgsi/tgsi_exec.h"
|
||||
#include "sp_buffer.h"
|
||||
#include "sp_clear.h"
|
||||
#include "sp_context.h"
|
||||
#include "sp_flush.h"
|
||||
|
|
@ -203,6 +204,10 @@ softpipe_create_context(struct pipe_screen *screen,
|
|||
softpipe->tgsi.image[i] = sp_create_tgsi_image();
|
||||
}
|
||||
|
||||
for (i = 0; i < PIPE_SHADER_TYPES; i++) {
|
||||
softpipe->tgsi.buffer[i] = sp_create_tgsi_buffer();
|
||||
}
|
||||
|
||||
softpipe->dump_fs = debug_get_bool_option( "SOFTPIPE_DUMP_FS", FALSE );
|
||||
softpipe->dump_gs = debug_get_bool_option( "SOFTPIPE_DUMP_GS", FALSE );
|
||||
|
||||
|
|
@ -288,6 +293,16 @@ softpipe_create_context(struct pipe_screen *screen,
|
|||
(struct tgsi_image *)
|
||||
softpipe->tgsi.image[PIPE_SHADER_GEOMETRY]);
|
||||
|
||||
draw_buffer(softpipe->draw,
|
||||
PIPE_SHADER_VERTEX,
|
||||
(struct tgsi_buffer *)
|
||||
softpipe->tgsi.buffer[PIPE_SHADER_VERTEX]);
|
||||
|
||||
draw_buffer(softpipe->draw,
|
||||
PIPE_SHADER_GEOMETRY,
|
||||
(struct tgsi_buffer *)
|
||||
softpipe->tgsi.buffer[PIPE_SHADER_GEOMETRY]);
|
||||
|
||||
if (debug_get_bool_option( "SOFTPIPE_NO_RAST", FALSE ))
|
||||
softpipe->no_rast = TRUE;
|
||||
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ struct softpipe_context {
|
|||
struct pipe_sampler_view *sampler_views[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS];
|
||||
|
||||
struct pipe_image_view images[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES];
|
||||
struct pipe_shader_buffer buffers[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_BUFFERS];
|
||||
struct pipe_viewport_state viewports[PIPE_MAX_VIEWPORTS];
|
||||
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
|
||||
struct pipe_index_buffer index_buffer;
|
||||
|
|
@ -174,6 +175,7 @@ struct softpipe_context {
|
|||
struct {
|
||||
struct sp_tgsi_sampler *sampler[PIPE_SHADER_TYPES];
|
||||
struct sp_tgsi_image *image[PIPE_SHADER_TYPES];
|
||||
struct sp_tgsi_buffer *buffer[PIPE_SHADER_TYPES];
|
||||
} tgsi;
|
||||
|
||||
struct tgsi_exec_machine *fs_machine;
|
||||
|
|
|
|||
|
|
@ -63,14 +63,15 @@ static void
|
|||
exec_prepare( const struct sp_fragment_shader_variant *var,
|
||||
struct tgsi_exec_machine *machine,
|
||||
struct tgsi_sampler *sampler,
|
||||
struct tgsi_image *image )
|
||||
struct tgsi_image *image,
|
||||
struct tgsi_buffer *buffer )
|
||||
{
|
||||
/*
|
||||
* Bind tokens/shader to the interpreter's machine state.
|
||||
*/
|
||||
tgsi_exec_machine_bind_shader(machine,
|
||||
var->tokens,
|
||||
sampler, image, NULL);
|
||||
sampler, image, buffer);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -259,7 +259,6 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
|
|||
case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:
|
||||
case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
|
||||
case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
|
||||
case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
|
||||
case PIPE_CAP_INVALIDATE_BUFFER:
|
||||
case PIPE_CAP_GENERATE_MIPMAP:
|
||||
case PIPE_CAP_STRING_MARKER:
|
||||
|
|
@ -272,6 +271,8 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
|
|||
case PIPE_CAP_PCI_FUNCTION:
|
||||
case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
|
||||
return 0;
|
||||
case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
|
||||
return 4;
|
||||
}
|
||||
/* should only get here on unhandled cases */
|
||||
debug_printf("Unexpected PIPE_CAP %d query\n", param);
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@
|
|||
|
||||
struct tgsi_sampler;
|
||||
struct tgsi_image;
|
||||
struct tgsi_buffer;
|
||||
struct tgsi_exec_machine;
|
||||
struct vertex_info;
|
||||
|
||||
|
|
@ -83,7 +84,8 @@ struct sp_fragment_shader_variant
|
|||
void (*prepare)(const struct sp_fragment_shader_variant *shader,
|
||||
struct tgsi_exec_machine *machine,
|
||||
struct tgsi_sampler *sampler,
|
||||
struct tgsi_image *image);
|
||||
struct tgsi_image *image,
|
||||
struct tgsi_buffer *buffer);
|
||||
|
||||
unsigned (*run)(const struct sp_fragment_shader_variant *shader,
|
||||
struct tgsi_exec_machine *machine,
|
||||
|
|
|
|||
|
|
@ -344,7 +344,8 @@ update_fragment_shader(struct softpipe_context *softpipe, unsigned prim)
|
|||
softpipe->fs_machine,
|
||||
(struct tgsi_sampler *) softpipe->
|
||||
tgsi.sampler[PIPE_SHADER_FRAGMENT],
|
||||
(struct tgsi_image *)softpipe->tgsi.image[PIPE_SHADER_FRAGMENT]);
|
||||
(struct tgsi_image *)softpipe->tgsi.image[PIPE_SHADER_FRAGMENT],
|
||||
(struct tgsi_buffer *)softpipe->tgsi.buffer[PIPE_SHADER_FRAGMENT]);
|
||||
}
|
||||
else {
|
||||
softpipe->fs_variant = NULL;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "sp_context.h"
|
||||
#include "sp_state.h"
|
||||
#include "sp_image.h"
|
||||
#include "sp_buffer.h"
|
||||
|
||||
static void softpipe_set_shader_images(struct pipe_context *pipe,
|
||||
unsigned shader,
|
||||
|
|
@ -51,7 +52,34 @@ static void softpipe_set_shader_images(struct pipe_context *pipe,
|
|||
}
|
||||
}
|
||||
|
||||
static void softpipe_set_shader_buffers(struct pipe_context *pipe,
|
||||
unsigned shader,
|
||||
unsigned start,
|
||||
unsigned num,
|
||||
struct pipe_shader_buffer *buffers)
|
||||
{
|
||||
struct softpipe_context *softpipe = softpipe_context(pipe);
|
||||
unsigned i;
|
||||
assert(shader < PIPE_SHADER_TYPES);
|
||||
assert(start + num <= Elements(softpipe->buffers[shader]));
|
||||
|
||||
/* set the new images */
|
||||
for (i = 0; i < num; i++) {
|
||||
int idx = start + i;
|
||||
|
||||
if (buffers) {
|
||||
pipe_resource_reference(&softpipe->tgsi.buffer[shader]->sp_bview[idx].buffer, buffers[i].buffer);
|
||||
softpipe->tgsi.buffer[shader]->sp_bview[idx] = buffers[i];
|
||||
}
|
||||
else {
|
||||
pipe_resource_reference(&softpipe->tgsi.buffer[shader]->sp_bview[idx].buffer, NULL);
|
||||
memset(&softpipe->tgsi.buffer[shader]->sp_bview[idx], 0, sizeof(struct pipe_shader_buffer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void softpipe_init_image_funcs(struct pipe_context *pipe)
|
||||
{
|
||||
pipe->set_shader_images = softpipe_set_shader_images;
|
||||
pipe->set_shader_buffers = softpipe_set_shader_buffers;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue